package com.yaodian100.ec.shopping.service.impl;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.math.NumberUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.yaodian100.core.common.dao.ObjectDao;
import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.exception.CoreException;
import com.yaodian100.core.common.service.BaseManager;
import com.yaodian100.core.common.service.impl.DomainServiceImpl;
import com.yaodian100.core.common.utils.DateUtil;
import com.yaodian100.core.common.utils.ServerValue;
import com.yaodian100.core.common.utils.StringUtils;
import com.yaodian100.ec.campaign.entity.Campaign;
import com.yaodian100.ec.campaign.entity.CampaignExtend;
import com.yaodian100.ec.campaign.entity.CampaignProduct;
import com.yaodian100.ec.campaign.service.CampaignProductService;
import com.yaodian100.ec.campaign.service.CampaignService;
import com.yaodian100.ec.category.entity.Category;
import com.yaodian100.ec.category.service.CategoryService;
import com.yaodian100.ec.member.entity.ImageValid;
import com.yaodian100.ec.member.entity.Member;
import com.yaodian100.ec.member.service.MemberService;
import com.yaodian100.ec.product.dao.SpecificationInventoryDao;
import com.yaodian100.ec.product.entity.AddOnProduct;
import com.yaodian100.ec.product.entity.Product;
import com.yaodian100.ec.product.entity.ProductCategory;
import com.yaodian100.ec.product.entity.Specification;
import com.yaodian100.ec.product.entity.SpecificationInventory;
import com.yaodian100.ec.product.service.ProductService;
import com.yaodian100.ec.shelf.entity.Shelf;
import com.yaodian100.ec.shelf.entity.ShelfTuangou;
import com.yaodian100.ec.shelf.service.ShelfService;
import com.yaodian100.ec.shelf.service.ShelfTuangouService;
import com.yaodian100.ec.shopping.entity.ApplyCampaign;
import com.yaodian100.ec.shopping.entity.CartOrderProduct;
import com.yaodian100.ec.shopping.entity.CartOrderProductDetail;
import com.yaodian100.ec.shopping.entity.CartOrders;
import com.yaodian100.ec.shopping.service.CartOrdersService;
import com.yaodian100.ec.timelimitsale.service.TimeLimitSaleService;

public class CartOrdersServiceImpl extends DomainServiceImpl<CartOrders> implements CartOrdersService {
	private ObjectDao<CartOrderProductDetail> cartOrderProductDetailDao;
	private SpecificationInventoryDao specificationinventoryDao;// 獨立的dao

	@Autowired
	private MemberService memberService;
	@Autowired
	private ProductService productService;
	@Autowired
	private ShelfService shelfService;
	@Autowired
	private CampaignProductService campaignProductService;
	@Autowired
	private CampaignService campaignService;
	@Autowired
	private CategoryService categoryService;
	@Autowired
	private BaseManager baseMgr;
	@Autowired
	private TimeLimitSaleService timeLimitSaleService;
	@Autowired
	private ShelfTuangouService shelfTuangouService;

	/** default constructor */
	public CartOrdersServiceImpl() {
		super();
	}

	@Transactional(readOnly = false, timeout = 5)
	public CartOrders addProductForStep1(String memberId, String cartId, String productId, List<String> productOption,
			Long specId, int qty, String categoryPath, List<String> addOnOptions) throws CoreException {
		return addProductBase(memberId, cartId, productId, productOption, specId, qty, categoryPath, addOnOptions, true);
	}

	@Transactional(readOnly = false, timeout = 5)
	public CartOrders addProduct(String memberId, String cartId, String productId, List<String> productOption,
			Long specId, int qty, String categoryPath, List<String> addOnOptions) throws CoreException {
		// 暂时先将数量为0的自购物车移除
		return addProductBase(memberId, cartId, productId, productOption, specId, qty, categoryPath, addOnOptions, true);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.shopping.service.CartOrdersService#addProduct(java.lang.String, java.lang.String,
	 * java.lang.String, java.lang.Long, int, java.lang.String, java.util.List)
	 */
	private CartOrders addProductBase(String memberId, String cartId, String productId, List<String> productOption,
			Long specId, int qty, String categoryPath, List<String> addOnOptions, boolean skipZeroPresent)
			throws CoreException {
		CartOrders entity = getCart(memberId, cartId);
		if (entity == null) {
			throw new CoreException("errors.cart.null", cartId, memberId);
		}

		Product product = productService.get(productId);
		Shelf shelf = null;
		Specification spec = null;
		SpecificationInventory specInv = null;
		// 检核商品主档是否存在
		if (product == null) {
			throw new CoreException("errors.product.null", productId);
		} else {
			// 若 categoryPath 未传入, 预设为 product.mainCategory.categoryPath
			if (StringUtils.isBlank(categoryPath)) {
				Category c = categoryService.get(Long.valueOf(product.getMainCategoryID()));
				categoryPath = c.getCategoryPath();
			} else {
				// 有傳入 categoryPath
				Map<String, ProductCategory> m = productService.getProductCategoryByProduct(productId);
				if (NumberUtils.isNumber(categoryPath)) {
					// 修正 categoryPath 傳入 categoryId, 並驗證是有正確上架目錄
					if (m.get(categoryPath) != null) {
						categoryPath = m.get(categoryPath).getCategoryPath();
					} else {
						// 找不到 categoryPath
						Category c = categoryService.get(Long.valueOf(product.getMainCategoryID()));
						categoryPath = c.getCategoryPath();
					}
				} else {
					boolean hasPC = false;
					for (ProductCategory pc : m.values()) {
						if (pc.getCategoryPath().equals(categoryPath)) {
							hasPC = true;
						}
					}
					if (!hasPC) {
						logger.error("上架目錄檔不正確, cartId:{}, productId:{}, categoryPath:{}", new Object[] { entity.getCartId(),
								productId, categoryPath });
						// 上架目錄檔不正確, 重新複寫為 product.mainCategory.categpryPath
						Category c = categoryService.get(Long.valueOf(product.getMainCategoryID()));
						categoryPath = c.getCategoryPath();
					}
				}
			}

			Map<String, Specification> specMap = productService.getSpecifications(productId);
			// 未给予 spec
			if (specId == null || specId.intValue() == 0) {
				// 找寻第一个 spec 作为 default spec
				if (specMap != null && !specMap.isEmpty()) {
					spec = specMap.values().iterator().next();
				}
			} else {
				if (specMap != null && !specMap.isEmpty()) {
					spec = specMap.get(specId.toString());
				}
			}
			if (spec == null) {
				throw new CoreException("errors.specification.null", productId);
			}

			// 确认库存
			// try {
			// if (product.getProductType() != 6) {
			// logger.info("product.getProductType() != 6:{}");
			// specInv = productService.getSpecificationInventory(productId, spec.getSpecificationId());
			// }
			// qty = checkSpecInvReturnQty(product, spec, specInv, qty);
			// } catch (Exception e) {
			// e.printStackTrace();
			// }

			// 确认上架档
			shelf = shelfService.getActiveShelfByProductId(productId);
			if (shelf == null) {
				throw new CoreException("errors.shelf.null", productId);
			} else if (shelf.getShelfPrice().floatValue() <= 0.0f) {
				// 阻擋價格為 0, 贈品等應該使用 addPromoteProduct
				logger.error("商品金額 <= 0, memberId:" + memberId + ",cartId:" + memberId + ",productId:" + productId + ",price:"
						+ shelf.getShelfPrice());
				throw new CoreException("errors.shelf.price", productId, shelf.getShelfId().toString(), shelf.getShelfPrice()
						.toString());
			}
		}
		CartOrderProduct cop = null;
		CartOrderProductDetail copd = null;

		switch (product.getProductType()) {
		case 0:
		case 7:
			// 主
			cop = new CartOrderProduct(product, spec, shelf, categoryPath, qty, null);
			entity.addCartOrderProduct(cop);
			// logger.debug("op seq:{}", cop.getProdSeq());

			copd = new CartOrderProductDetail(product, spec, shelf, qty, null);
			cop.addDetail(copd);
			// logger.debug("opd seq:{}/{}", copd.getProdSeq(), copd.getDetailSeq());
			break;
		case 1:
			// 预 (購物車商品數量應當為 1, 不可呼叫 addProduct)
			if (entity.getCartOrderProducts().size() == 0) {
				cop = new CartOrderProduct(product, spec, shelf, categoryPath, qty, null);
				entity.addCartOrderProduct(cop);
			} else {
				// 预购不可合并结帐
				throw new CoreException("errors.cart.product.type", entity.getCartId(), productId);
			}

			copd = new CartOrderProductDetail(product, spec, shelf, qty, null);
			cop.addDetail(copd);
			break;
		case 6:
			// N选M

			int count = product.getPickupQty(); // count 為 N選M 中的M 應與 productOption 數量相同

			Set<String> prodSet = new HashSet();
			prodSet.addAll(productOption);
			if (prodSet.size() != count) {
				logger.warn("加N选M失败, Card:{}, Product:{}, prodOpt:{}", new Object[] { cartId, productId, prodSet });
				throw new CoreException("errors.cart.product.type.nm", productId, entity.getCartId());
			}

			cop = new CartOrderProduct(product, spec, shelf, categoryPath, qty, null);
			entity.addCartOrderProduct(cop);

			if (productOption != null) {
				Map<String, AddOnProduct> nmProductMap = productService.getAddOnProducts(productId, true);

				for (String prodOption : productOption) {
					String nmProdId = "", nmSpecId = "";
					Specification addOnSpec;
					SpecificationInventory si = null;
					if (prodOption.indexOf(";") != -1) {
						nmProdId = StringUtils.split(prodOption, ";")[0];
						nmSpecId = StringUtils.split(prodOption, ";")[1];
						addOnSpec = productService.getSpecifications(nmProdId).get(nmSpecId);
						Map<String, SpecificationInventory> siMap = productService.getSpecificationInventoryMap(nmProdId);
						si = siMap.get(nmSpecId);
					} else {
						nmProdId = prodOption;
						Map<String, SpecificationInventory> siMap = productService.getSpecificationInventoryMap(nmProdId);
						for (SpecificationInventory tmpSi : siMap.values()) {
							if (tmpSi.getInventory() > 0) {
								si = tmpSi;
								nmSpecId = tmpSi.getSpecId().toString();
								break;
							}
						}
						addOnSpec = productService.getSpecifications(nmProdId).get(nmSpecId);
					}
					AddOnProduct aop = nmProductMap.get(nmProdId);

					// addOnPrice > 0, 表示加購
					boolean isAdd = false;
					// if (si != null && aop != null && aop.getAddOnPrice().floatValue() == -1f && si.getInventory() > 0) {
					if (si != null && aop != null && aop.getAddOnPrice().floatValue() == -1f) {
						// 库存需要 > 0
						Product productProfile = productService.get(aop.getAddOnProductId());
						copd = new CartOrderProductDetail(aop, productProfile, addOnSpec, 1);
						cop.addDetail(copd);
						isAdd = true;
						count--;
					}

					if (!isAdd) {
						logger.warn("加N选M失败, Card:{}, Product:{}, prodOpt:{}", new Object[] { cartId, productId, prodOption });
					}
				}
				// 虛擬商品不需要加入 detail, 將價格平均分到各選購商品
				Iterator<CartOrderProductDetail> it = cop.getDetails().iterator();
				BigDecimal sunPrice = BigDecimal.ZERO;
				BigDecimal avgPrice = cop.getUnitPrice().setScale(1).divide(BigDecimal.valueOf(product.getPickupQty()),
						RoundingMode.DOWN);
				while (it.hasNext()) {
					copd = it.next();
					if (it.hasNext()) {
						copd.setAmount(avgPrice);
						sunPrice = sunPrice.add(avgPrice);
					} else {
						copd.setAmount(cop.getUnitPrice().subtract(sunPrice));
					}
				}
			}
			if (count != 0) {
				throw new CoreException("errors.cart.product.type.nm", productId);
			}
			break;
		default:
			throw new CoreException("errors.product.type");
		}

		Map<String, AddOnProduct> addOnProductMap = productService.getAddOnProducts(productId, false);
		// 处理加購
		if (addOnOptions != null) {
			for (String addOnOption : addOnOptions) {
				if (StringUtils.isBlank(addOnOption)) {
					continue;
				}
				if (addOnOption.indexOf(";") == -1) {
					logger.warn("加購失败, Card:{}, Product:{}, AddOn:{}", new Object[] { cartId, productId, addOnOption });
				}

				String addOnProdId = StringUtils.split(addOnOption, ";")[0];
				String addOnSpecId = StringUtils.split(addOnOption, ";")[1];
				Specification addOnSpec = productService.getSpecifications(addOnProdId).get(addOnSpecId);
				Map<String, SpecificationInventory> siMap = productService.getSpecificationInventoryMap(addOnProdId);
				SpecificationInventory si = siMap.get(addOnSpecId);
				AddOnProduct aop = addOnProductMap.get(addOnProdId);

				boolean isAdd = false;
				// addOnPrice > 0, 表示加購
				if (aop != null && aop.getAddOnPrice().floatValue() > 0.0f) {
					if (si.getInventory() > 0) {
						// 库存 > 0
						Product productProfile = productService.get(aop.getAddOnProductId());
						copd = new CartOrderProductDetail(aop, productProfile, addOnSpec, 1);
						cop.addDetail(copd);
						isAdd = true;
					}
					if (!isAdd) {
						logger.warn("加購失败, Card:{}, Product:{}, AddOn:{}", new Object[] { cartId, productId,
								aop.getAddOnProductId() });
					}
				} else {
					logger.warn("加購失败, Card:{}, Product:{}, AddOn:{}", new Object[] { cartId, productId, addOnOption });
				}
			}
		}

		// 处理贈品
		for (AddOnProduct aop : addOnProductMap.values()) {
			boolean isAdd = false;
			if (aop.getAddOnPrice().floatValue() == 0.0f) {
				// addOnPrice 为 0, 表示赠品
				Map<String, SpecificationInventory> siMap = productService
						.getSpecificationInventoryMap(aop.getAddOnProductId());
				Specification addOnSpec = null;
				for (SpecificationInventory si : siMap.values()) {
					if (skipZeroPresent && si.getInventory() <= 0) {
						continue;
					}
					// if (si.getInventory() > 0) {
					// 找一个赠品库存 > 0
					addOnSpec = productService.getSpecification(si.getSpecId());
					Product productProfile = productService.get(aop.getAddOnProductId());
					copd = new CartOrderProductDetail(aop, productProfile, addOnSpec, qty);
					cop.addDetail(copd);
					isAdd = true;
					break;
					// }
				}
				if (!isAdd) {
					logger.warn("加入赠品失败, Card:{}, Product:{}, AddOn;{}", new Object[] { cartId, productId,
							aop.getAddOnProductId() });
				}
			}
		}
		// for (CartOrderProduct cop_ : entity.getCartOrderProducts()) {
		// System.out.println(cop_.getProdSpecName());
		// }
		return save(entity);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.shopping.service.CartOrdersService#addPromoteProduct(java.lang.String, java.lang.String,
	 * java.lang.String, java.lang.Long, int, java.lang.String, java.lang.String)
	 */
	@Transactional(readOnly = false, timeout = 5)
	public CartOrders addPromoteProduct(CartOrders cart, String promoteId, String type, String productId, String specId)
			throws CoreException {
		if (cart == null) {
			throw new CoreException("errors.cart.null");
		}
		Product product = null;
		Shelf shelf = null;
		CampaignProduct cp = null;
		if ("2".equals(type)) {
			if (productId == null) {
				Campaign c = campaignService.get(promoteId);
				productId = c.getTypeExtends().get(0).getCampaignTypeExtension();
			}
			product = productService.get(productId);

			// 假造一個促銷活動/上架檔. 以便滿足 CartOrderProduct, CartOrderProductDetail 建構
			cp = new CampaignProduct(promoteId, new Date(), new Date(), productId, BigDecimal.ZERO, 1, null, null);
			shelf = new Shelf();
			shelf.setProductId(productId);
			shelf.setShelfPrice(BigDecimal.ZERO);
		} else if ("5".equals(type)) {
			cp = campaignProductService.get(promoteId);
			if (cp != null && cp.isEnable()) {
				if (!cp.isDelete()) {
					Date now = DateUtil.getCurrentTime();
					if (!DateUtil.checkDateBetween(now, cp.getStartDateTime(), cp.getEndDateTime(), true, true)) {
						cp = null;
					} else {
						productId = cp.getProductId();
						product = productService.get(productId);
						// 假造一个上架檔. 以便滿足 CartOrderProduct, CartOrderProductDetail 建構
						shelf = new Shelf();
						shelf.setProductId(productId);
						shelf.setShelfPrice(cp.getPrice());
						// // 确认上架档
						// shelf = shelfService.getActiveShelfByProductId(productId);
						// if (shelf == null) {
						// throw new CoreException("errors.shelf.null", productId);
					}
				} else {
					cp = null;
				}
			} else {
				cp = null;
			}
		} else {
			throw new CoreException("errors.cart.promote.type", cart.getCartId(), promoteId, type);
		}
		if (cp == null) {
			throw new CoreException("errors.campaignproduct.null", promoteId);
		}
		Specification spec = null;
		String categoryPath = null;
		int qty = 1;
		// 检核商品主档是否存在
		if (product == null) {
			throw new CoreException("errors.campaignproduct.product.null", productId);
		} else {
			Category c = categoryService.get(Long.valueOf(product.getMainCategoryID()));
			categoryPath = c.getCategoryPath();

			// 确认库存
			Map<String, SpecificationInventory> specInvMap = productService.getSpecificationInventoryMap(productId);
			Long tmpSpecId = null;
			int specAt = 0;
			if (specInvMap != null) {
				if (null != specId && StringUtils.isNotBlank(specId)) {
					tmpSpecId = Long.parseLong(specId);
					spec = productService.getSpecification(tmpSpecId);
				} else {
					for (SpecificationInventory si : specInvMap.values()) {
						if (specAt == 0) {
							tmpSpecId = si.getSpecId();
						}
						if (si.getInventory() > 0) {
							spec = productService.getSpecification(si.getSpecId());
							break;
						}
						specAt++;
					}
				}
			}
			if (spec == null) {
				// throw new CoreException("errors.specification.null", productId);
				spec = productService.getSpecification(tmpSpecId);
				qty = 0;
			}
		}
		switch (product.getProductType()) {
		case 0:
		case 7:
		case 2:
			// 僅主商品, 贈品可已作為活動商品
			CartOrderProduct cop = new CartOrderProduct(product, spec, shelf, categoryPath, qty, cp);
			cop.setProdTp(type);
			cart.addCartOrderProduct(cop);
			CartOrderProductDetail copd = new CartOrderProductDetail(product, spec, shelf, qty, cp);
			copd.setDetailTp(type);
			cop.addDetail(copd);
			break;
		default:
			throw new CoreException("errors.cart.product.type");
		}
		return cart;

	}

	@Transactional(readOnly = false, timeout = 5)
	public CartOrders addPromoteProduct(CartOrders cart, String promoteId, String type) throws CoreException {
		return addPromoteProduct(cart, promoteId, type, null);
	}

	@Transactional(readOnly = false, timeout = 5)
	public CartOrders addPromoteProduct(CartOrders cart, String promoteId, String type, String specId)
			throws CoreException {
		return addPromoteProduct(cart, promoteId, type, null, specId);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.shopping.service.CartOrdersService#calcuteCart(com.yaodian100.ec.shopping.entity.CartOrders,
	 * java.util.Map)
	 */
	@Override
	public CartOrders calculateCart(CartOrders cart, Map<String, String> optional) throws CoreException {
		if (cart == null) {
			throw new CoreException("errors.cart.null");
		}
		boolean redGreenCategory = false;
		// 重設 applyCampaign 數據
		cart.getApplyCampaign().clear();
		for (CartOrderProduct cop : cart.getCartOrderProducts()) {
			// 重設 applyCampaign 數據
			cop.getApplyCampaign().clear();
			// 預設將 discount 設為0
			cop.setDiscount(BigDecimal.ZERO);
		}

		// 將符合的活動註冊到 cartOrderPorducts
		for (CartOrderProduct cop : cart.getCartOrderProducts()) {
			// 贈品與滿額購
			// N選M 修改为允许参加行销活動
			if ("2".equals(cop.getProdTp()) || "5".equals(cop.getProdTp())) {
				continue;
			}
			// 取得所有符合商品目錄的促銷活動
			for (Campaign c : campaignService.getValidCampaign(cop.getCategoryPath(), cop.getProdId(), optional)) {
				ApplyCampaign ac = cart.getApplyCampaign().get(c.getUuid());
				if (ac == null) {
					// 該活動對此訂單是新活動, 註冊到 cart 中
					ac = new ApplyCampaign(c);
					cart.getApplyCampaign().put(c.getUuid(), ac);
				}
				// 符合紅綠標活動,先分別加入到ac.getRedMap(), ac.getGreenMap(),id/qty/specId 當key,unitprice當value,作排序使用
				if (StringUtils.isNotBlank(c.getRedRange()) && StringUtils.isNotBlank(c.getGreenRange())
						&& Campaign.Range.RedGreenCategory.equals(c.getRange())) {
					String key = cop.getProdId() + "/" + cop.getQty() + "/" + cop.getProdSpecId();// id/qty/specId 當key,
					for (String cp : StringUtils.split(c.getRedRange(), ",")) {
						if ((cop.getCategoryPath() + "/").startsWith(cp + "/")) {
							ac.setRedSumQty(ac.getRedSumQty() + cop.getQty());// 紅標的數量
							ac.getRedMap().put(key, Double.valueOf(String.valueOf(cop.getUnitPrice())));// key加上redQty是防止key相同,导致後者盖前者,unitprice當value,作排序使用
						}
					}
					for (String cp : StringUtils.split(c.getGreenRange(), ",")) {
						if ((cop.getCategoryPath() + "/").startsWith(cp + "/")) {
							ac.setGreenSumQty(ac.getGreenSumQty() + cop.getQty());// 綠標的數量
							ac.getGreenMap().put(key, Double.valueOf(String.valueOf(cop.getUnitPrice())));// key加上greenQty是防止key相同,导致後者盖前者,
						}
					}
					// 算符合紅綠標的組數,一個紅標+一個綠標=1組
					if (ac.getRedSumQty() > 0 && ac.getGreenSumQty() > 0 && ac.getRedSumQty() <= ac.getGreenSumQty()) {
						ac.setSumQty(ac.getRedSumQty());
					} else if (ac.getRedSumQty() > 0 && ac.getGreenSumQty() > 0 && ac.getRedSumQty() > ac.getGreenSumQty()) {
						ac.setSumQty(ac.getGreenSumQty());
					} else {
						ac.setSumQty(0);
					}
					// 如果有符合紅綠標組數的,redGreenCategory = true
					if (ac.getSumQty() > 0) {
						redGreenCategory = true;
						ac.setRgCategory(true);
					}
				} else {
					ac.getApplyProductIds().add(cop.getProdId());
					ac.setSumQty(ac.getSumQty() + cop.getQty());
					ac.setSumAmount(ac.getSumAmount().add(cop.getTotalPrice()));
					cop.getApplyCampaign().add(ac);
				}
			}
		}
		// redGreenCategory = true時,就會開始計算符合紅綠標的商品,及計算sumaount,并將該applycampaign加入到符合的cartorderproduct裡
		if (redGreenCategory) {
			for (Map.Entry<String, ApplyCampaign> map : cart.getApplyCampaign().entrySet()) {
				ApplyCampaign ac = map.getValue();
				if (ac.isRgCategory()) {
					ac.setSumAmount(BigDecimal.ZERO);
					int red = ac.getSumQty();
					int green = ac.getSumQty();
					// 找出符合紅標的商品
					for (int i = 0; i < ac.getRedSortList().size(); i++) {
						String object[] = StringUtils.split(ac.getRedSortList().get(i).getKey(), "/");
						String id = object[0];// 商品編號
						Integer prodQry = Integer.valueOf(object[1]);// 購買數量
						String specId = object[2];// specId,防止加入相同的商品
						BigDecimal price = BigDecimal.valueOf(Double.valueOf(ac.getRedSortList().get(i).getValue()));// 售價
						BigDecimal total = BigDecimal.ZERO;// 用來計算符合的金額(符合的數量*售價)
						if (red > 0) {
							if (prodQry >= red) {
								total = total.add(price.multiply(BigDecimal.valueOf(red)));// 如果購買數量大於紅綠標的組數,以紅綠標的組數*售價
								ac.getApplyProductIds().add(id);
								ac.setSumAmount(ac.getSumAmount().add(total));// 將符合的金額加入到sumAmount
							} else {
								ac.getApplyProductIds().add(id);
								total = total.add(price.multiply(BigDecimal.valueOf(prodQry)));// 如果購買數量小於紅綠標的組數,以購買的數量*售價
								ac.setSumAmount(ac.getSumAmount().add(total));// 將符合的金額加入到sumAmount
							}
							// 將有符合的cartOrderProduct加入此applyCampaign
							for (CartOrderProduct cop : cart.getCartOrderProducts()) {
								if (cop.getProdId().equals(id) && cop.getProdSpecId().equals(specId)) {
									cop.getApplyCampaign().add(ac);
								}
							}
							red -= prodQry;
						}
					}
					// 找出符合綠標的商品
					for (int i = 0; i < ac.getGreenSortList().size(); i++) {
						String object[] = StringUtils.split(ac.getGreenSortList().get(i).getKey(), "/");// 取出key
						String id = object[0];// 商品編號
						String specId = object[2];// specId,防止加入相同的商品
						Integer prodQry = Integer.valueOf(object[1]);// 購買數量
						BigDecimal price = BigDecimal.valueOf(Double.valueOf(ac.getRedSortList().get(i).getValue()));// 售價
						BigDecimal total = BigDecimal.ZERO;
						if (green > 0) {
							if (prodQry >= green) {
								total = total.add(price.multiply(BigDecimal.valueOf(green)));// 如果購買數量大於紅綠標的組數,以紅綠標的組數*售價
								ac.getApplyProductIds().add(id);
								ac.setSumAmount(ac.getSumAmount().add(total));// 將符合的金額加入到sumAmount
							} else {
								ac.getApplyProductIds().add(id);
								total = total.add(price.multiply(BigDecimal.valueOf(prodQry)));// 如果購買數量小於紅綠標的組數,以購買的數量*售價
								ac.setSumAmount(ac.getSumAmount().add(total));// 將符合的金額加入到sumAmount
							}
							// 將有符合的cartOrderProduct加入此applyCampaign
							for (CartOrderProduct cop : cart.getCartOrderProducts()) {
								if (cop.getProdId().equals(id) && cop.getProdSpecId().equals(specId)) {
									cop.getApplyCampaign().add(ac);
								}
							}
							green -= prodQry;
						}
					}
				}
			}
		}

		cart = calculateCartObj(cart, optional);
		return cart;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.yaodian100.ec.shopping.service.CartOrdersService#calculateCart(com.yaodian100.ec.shopping.entity.CartOrders,
	 * java.util.Map, java.util.List)
	 */
	@Override
	public CartOrders calculateCart(CartOrders cart, Map<String, String> optional, List<String> campaigns)
			throws CoreException {
		if (cart == null) {
			throw new CoreException("errors.cart.null");
		}
		boolean redGreenCategory = false;
		// 重設 applyCampaign 數據
		cart.getApplyCampaign().clear();
		for (CartOrderProduct cop : cart.getCartOrderProducts()) {
			// 重設 applyCampaign 數據
			cop.getApplyCampaign().clear();
			// 預設將 discount 設為0
			cop.setDiscount(BigDecimal.ZERO);
		}

		// 將符合的活動註冊到 cartOrderPorducts
		for (CartOrderProduct cop : cart.getCartOrderProducts()) {
			// 贈品與滿額購
			// N選M 修改为允许参加行销活動
			if ("2".equals(cop.getProdTp()) || "5".equals(cop.getProdTp())) {
				continue;
			}
			// 取得所有符合商品目錄的促銷活動
			for (Campaign c : campaignService.getValidCampaign(cop.getCategoryPath(), cop.getProdId(), optional)) {
				ApplyCampaign ac = cart.getApplyCampaign().get(c.getUuid());
				if (ac == null) {
					// 該活動對此訂單是新活動, 註冊到 cart 中
					ac = new ApplyCampaign(c);
					cart.getApplyCampaign().put(c.getUuid(), ac);
				}
				// 符合紅綠標活動,先分別加入到ac.getRedMap(), ac.getGreenMap(),id/qty/specId 當key,unitprice當value,作排序使用
				if (StringUtils.isNotBlank(c.getRedRange()) && StringUtils.isNotBlank(c.getGreenRange())
						&& Campaign.Range.RedGreenCategory.equals(c.getRange())) {
					String key = cop.getProdId() + "/" + cop.getQty() + "/" + cop.getProdSpecId();// id/qty/specId 當key,
					for (String cp : StringUtils.split(c.getRedRange(), ",")) {
						if ((cop.getCategoryPath() + "/").startsWith(cp + "/")) {
							ac.setRedSumQty(ac.getRedSumQty() + cop.getQty());// 紅標的數量
							ac.getRedMap().put(key, Double.valueOf(String.valueOf(cop.getUnitPrice())));// key加上redQty是防止key相同,导致後者盖前者,unitprice當value,作排序使用
						}
					}
					for (String cp : StringUtils.split(c.getGreenRange(), ",")) {
						if ((cop.getCategoryPath() + "/").startsWith(cp + "/")) {
							ac.setGreenSumQty(ac.getGreenSumQty() + cop.getQty());// 綠標的數量
							ac.getGreenMap().put(key, Double.valueOf(String.valueOf(cop.getUnitPrice())));// key加上greenQty是防止key相同,导致後者盖前者,
						}
					}
					// 算符合紅綠標的組數,一個紅標+一個綠標=1組
					if (ac.getRedSumQty() > 0 && ac.getGreenSumQty() > 0 && ac.getRedSumQty() <= ac.getGreenSumQty()) {
						ac.setSumQty(ac.getRedSumQty());
					} else if (ac.getRedSumQty() > 0 && ac.getGreenSumQty() > 0 && ac.getRedSumQty() > ac.getGreenSumQty()) {
						ac.setSumQty(ac.getGreenSumQty());
					} else {
						ac.setSumQty(0);
					}
					// 如果有符合紅綠標組數的,redGreenCategory = true
					if (ac.getSumQty() > 0) {
						redGreenCategory = true;
						ac.setRgCategory(true);
					}
				} else {
					ac.getApplyProductIds().add(cop.getProdId());
					ac.setSumQty(ac.getSumQty() + cop.getQty());
					ac.setSumAmount(ac.getSumAmount().add(cop.getTotalPrice()));
					cop.getApplyCampaign().add(ac);
				}
			}
		}
		// redGreenCategory = true時,就會開始計算符合紅綠標的商品,及計算sumaount,并將該applycampaign加入到符合的cartorderproduct裡
		if (redGreenCategory) {
			for (Map.Entry<String, ApplyCampaign> map : cart.getApplyCampaign().entrySet()) {
				ApplyCampaign ac = map.getValue();
				if (ac.isRgCategory()) {
					ac.setSumAmount(BigDecimal.ZERO);
					int red = ac.getSumQty();
					int green = ac.getSumQty();
					// 找出符合紅標的商品
					for (int i = 0; i < ac.getRedSortList().size(); i++) {
						String object[] = StringUtils.split(ac.getRedSortList().get(i).getKey(), "/");
						String id = object[0];// 商品編號
						Integer prodQry = Integer.valueOf(object[1]);// 購買數量
						String specId = object[2];// specId,防止加入相同的商品
						BigDecimal price = BigDecimal.valueOf(Double.valueOf(ac.getRedSortList().get(i).getValue()));// 售價
						BigDecimal total = BigDecimal.ZERO;// 用來計算符合的金額(符合的數量*售價)
						if (red > 0) {
							if (prodQry >= red) {
								total = total.add(price.multiply(BigDecimal.valueOf(red)));// 如果購買數量大於紅綠標的組數,以紅綠標的組數*售價
								ac.getApplyProductIds().add(id);
								ac.setSumAmount(ac.getSumAmount().add(total));// 將符合的金額加入到sumAmount
							} else {
								ac.getApplyProductIds().add(id);
								total = total.add(price.multiply(BigDecimal.valueOf(prodQry)));// 如果購買數量小於紅綠標的組數,以購買的數量*售價
								ac.setSumAmount(ac.getSumAmount().add(total));// 將符合的金額加入到sumAmount
							}
							// 將有符合的cartOrderProduct加入此applyCampaign
							for (CartOrderProduct cop : cart.getCartOrderProducts()) {
								if (cop.getProdId().equals(id) && cop.getProdSpecId().equals(specId)) {
									cop.getApplyCampaign().add(ac);
								}
							}
							red -= prodQry;
						}
					}
					// 找出符合綠標的商品
					for (int i = 0; i < ac.getGreenSortList().size(); i++) {
						String object[] = StringUtils.split(ac.getGreenSortList().get(i).getKey(), "/");// 取出key
						String id = object[0];// 商品編號
						String specId = object[2];// specId,防止加入相同的商品
						Integer prodQry = Integer.valueOf(object[1]);// 購買數量
						BigDecimal price = BigDecimal.valueOf(Double.valueOf(ac.getRedSortList().get(i).getValue()));// 售價
						BigDecimal total = BigDecimal.ZERO;
						if (green > 0) {
							if (prodQry >= green) {
								total = total.add(price.multiply(BigDecimal.valueOf(green)));// 如果購買數量大於紅綠標的組數,以紅綠標的組數*售價
								ac.getApplyProductIds().add(id);
								ac.setSumAmount(ac.getSumAmount().add(total));// 將符合的金額加入到sumAmount
							} else {
								ac.getApplyProductIds().add(id);
								total = total.add(price.multiply(BigDecimal.valueOf(prodQry)));// 如果購買數量小於紅綠標的組數,以購買的數量*售價
								ac.setSumAmount(ac.getSumAmount().add(total));// 將符合的金額加入到sumAmount
							}
							// 將有符合的cartOrderProduct加入此applyCampaign
							for (CartOrderProduct cop : cart.getCartOrderProducts()) {
								if (cop.getProdId().equals(id) && cop.getProdSpecId().equals(specId)) {
									cop.getApplyCampaign().add(ac);
								}
							}
							green -= prodQry;
						}
					}
				}
			}
		}
		cart = calculateCartObj(cart, optional);
		return cart;
	}

	/**
	 * 實際計算 method
	 * 
	 * @param cart
	 * @param optional
	 * @return
	 */
	private CartOrders calculateCartObj(CartOrders cart, Map<String, String> optional) {
		String cookie = null, domain = null;
		if (optional != null) {
			cookie = StringUtils.defaultIfEmpty(optional.get("cookie"), "yaodian100");
			domain = StringUtils.defaultIfEmpty(optional.get("domain"), ServerValue.getFrontHostname().substring(7));
		} else {
			cookie = "yaodian100";
			domain = ServerValue.getFrontHostname().substring(7);
		}

		int sumQty = 0;
		// 為符合的活動計算對應的 discount
		for (CartOrderProduct cop : cart.getCartOrderProducts()) {
			// 贈品與滿額購 n選M 不包含在活動內
			if ("2".equals(cop.getProdTp()) || "5".equals(cop.getProdTp())) {
				continue;
			}
			sumQty += cop.getQty();
			for (ApplyCampaign ac : cop.getApplyCampaign()) {
				Campaign c = ac.getCampaign();
				boolean isValide = false;
				if ((StringUtils.isBlank(c.getCookie()) || c.getCookieArray().contains(cookie)) && domain.equals(c.getDomain())) {
					isValide = true;
				} else {
					isValide = false;
				}
				if (isValide) {
					for (CampaignExtend ce : c.getTypeExtends()) {
						// 檢核購買量是否滿足條件
						if (ce.getMinQty() <= ac.getSumQty() && ac.getSumQty() <= ce.getMaxQty()) {
							// 檢核訂單總價是否滿足條件
							if (ce.getMinOrderAmount().floatValue() <= ac.getSumAmount().floatValue()
									&& ac.getSumAmount().floatValue() <= ce.getMaxOrderAmount().floatValue()) {
								ac.setActive(true);
								switch (c.getType()) {
								case C01:
									// 2011-04 N选M/加价购加入行销活动. 故改用 totalPrice
									// 折扣金額為 (cop.totalPrice)*(1-ce.campaignTypeExtension/100)
									BigDecimal discount = new BigDecimal(ce.getCampaignTypeExtension()).setScale(1).divide(
											BigDecimal.valueOf(100));
									discount = (cop.getTotalPrice().multiply(BigDecimal.ONE.subtract(discount))).setScale(1,
											RoundingMode.HALF_EVEN);
									cop.setDiscount(cop.getDiscount().add(discount));
									// 最大 discount 不可超过 cop 的 totalPrice
									if (cop.getDiscount().compareTo(cop.getTotalPrice()) > 0) {
										cop.setDiscount(cop.getTotalPrice());
									}
									ac.setSumDiscount(ac.getSumDiscount().add(discount));
									break;
								case C02:
									// 紅綠標的折扣金額為 ce.campaignTypeExtension*符合的組數
									if (ac.isRgCategory()) {
										ac.setSumDiscount(new BigDecimal(ce.getCampaignTypeExtension()).multiply(
												BigDecimal.valueOf(ac.getSumQty())).setScale(1));
									} else {
										// 折扣金額為 ce.campaignTypeExtension
										ac.setSumDiscount(new BigDecimal(ce.getCampaignTypeExtension()).setScale(1));
									}
									break;
								case C03:
									ac.setFreeProductId(ce.getCampaignTypeExtension());
									break;
								}
							}
						}
					}
				}
			}
		}

		// 為 C02 平均將 discount 攤到各商品
		for (ApplyCampaign ac : cart.getApplyCampaign().values()) {
			if (Campaign.Type.C02.equals(ac.getCampaign().getType()) && ac.isActive()) {
				BigDecimal sumDiscount = BigDecimal.ZERO;
				// 需要對應售價的總計平均優惠
				BigDecimal sumAmount = BigDecimal.ZERO;
				for (CartOrderProduct cop : cart.getCartOrderProducts()) {
					if (cop.getApplyCampaign().contains(ac)) {
						sumAmount = sumAmount.add(cop.getTotalPrice());
					}
				}
				int count = ac.getApplyProductIds().size();
				for (CartOrderProduct cop : cart.getCartOrderProducts()) {
					if (cop.getApplyCampaign().contains(ac)) {
						if (count != 1) {
							BigDecimal bd = null;
							if (ac.getCampaign().getTypeExtends().get(0).getMinQty() != 0) {
								// 紅綠標
								if (ac.isRgCategory()) {
									bd = ac.getSumDiscount().multiply(cop.getTotalPrice()).divide(sumAmount, RoundingMode.DOWN).setScale(
											1, RoundingMode.DOWN);
								} else {
									// 優惠計算為總優惠金額以商品筆數平均攤提(總折扣金額*商品購買量/折扣商品總購買量)
									bd = ac.getSumDiscount().multiply(BigDecimal.valueOf(cop.getQty())).divide(
											BigDecimal.valueOf(ac.getSumQty()), RoundingMode.DOWN).setScale(1, RoundingMode.DOWN);
								}
								if (bd.compareTo(cop.getTotalPrice()) > 0) {
									// 若折扣金額大於主商品金額, 折扣金額為主商品金額
									bd = cop.getTotalPrice();
								}
							} else {
								// 優惠計算為總優惠金額以商品售價平均攤提
								bd = ac.getSumDiscount().multiply(cop.getTotalPrice()).divide(sumAmount, RoundingMode.DOWN).setScale(1,
										RoundingMode.DOWN);

							}
							cop.setDiscount(cop.getDiscount().add(bd));
							if (cop.getDiscount().compareTo(cop.getTotalPrice()) > 0) {
								cop.setDiscount(cop.getTotalPrice());
							}
							sumDiscount = sumDiscount.add(bd);
							logger.debug("C02 cart:{},productId:{},amount:{},discount:{}", new Object[] { cart.getCartId(),
									cop.getProdId(), cop.getTotalPrice(), cop.getDiscount() });
						} else {
							// count=1 表示最后一笔, 将 apply discount - sumDiscount 放入
							BigDecimal bd = ac.getSumDiscount().subtract(sumDiscount);
							if (bd.compareTo(cop.getTotalPrice()) > 0) {
								// 若折扣金額大於主商品金額, 折扣金額為主商品金額
								bd = cop.getTotalPrice();
							}
							cop.setDiscount(cop.getDiscount().add(bd));
							if (cop.getDiscount().compareTo(cop.getTotalPrice()) > 0) {
								cop.setDiscount(cop.getTotalPrice());
							}

							logger.debug("C02 cart:{},productId:{},amount:{},discount:{}", new Object[] { cart.getCartId(),
									cop.getProdId(), cop.getTotalPrice(), cop.getDiscount() });
						}
						count--;
					}
				}
			} else if (Campaign.Type.C03.equals(ac.getCampaign().getType())) {
				boolean hasProd = false;
				Iterator<CartOrderProduct> it = cart.getCartOrderProducts().iterator();
				while (it.hasNext()) {
					CartOrderProduct cop = it.next();
					if (ac.isActive()) {
						if (ac.getCampaign().getUuid().equals(cop.getCampaignId()) && "2".equals(cop.getProdTp())) {
							// 產品代碼相同的贈品
							hasProd = true;
						}
					} else {
						// 未達標準
						if (ac.getCampaign().getUuid().equals(cop.getCampaignId()) && "2".equals(cop.getProdTp())) {
							// 移除活動相同贈品, 移除
							it.remove();
						}
					}
				}
				if (ac.isActive() && !hasProd) {
					// 活動有效且未加入贈品
					cart = addPromoteProduct(cart, ac.getCampaign().getUuid(), "2", ac.getFreeProductId(), null);
				}
			}
		}
		// 算商品數量(贈品&n選m的主商品不算)
		cart.setProductSum(getCartOrderProductDetailListSize(cart).intValue());
		cart.getDiscount();
		cart.getAmount();
		cart.getMustPay();
		cart.getWeightSum();
		return cart;
	}

	public String checkSpecInventory(String cartId, String addCmpPd, Map<String, String> optional, String checkFlag)
			throws Exception {
		StringBuffer sbMsg = new StringBuffer();
		CartOrders cart = get(cartId);
		cart = this.calculateCart(cart, optional);
		List<CartOrderProductDetail> cartOrderProductDetailList = new ArrayList<CartOrderProductDetail>();
		for (CartOrderProduct cop : cart.getCartOrderProducts()) {
			cartOrderProductDetailList.addAll(cop.getDetails());
		}
		boolean mainProdNotEnough = false;
		if (cartOrderProductDetailList.size() > 0) {
			for (CartOrderProductDetail cartOrderProductDetail : cartOrderProductDetailList) {
				if (!Arrays.asList("2", "3", "5", "6").contains(cartOrderProductDetail.getDetailTp())) {// 不是赠品、加购、满额购
					SpecificationInventory specificationInventory = new SpecificationInventory();
					CommonCriteria criteria = new CommonCriteria();
					criteria.addEq("productId", cartOrderProductDetail.getProdId());
					criteria.addEq("specId", Long.parseLong(cartOrderProductDetail.getProdSpecId()));
					int specInvSize = specificationinventoryDao.getListSize(criteria).intValue();
					if (specInvSize > 0) {
						specificationInventory = specificationinventoryDao.getSingle(criteria, null);
						int availableInventory = specificationInventory.getInventory();
						Specification spec = (Specification) baseMgr.get(Specification.class, Long.valueOf(cartOrderProductDetail
								.getProdSpecId()));
						if (availableInventory <= 0 || availableInventory < cartOrderProductDetail.getQty()
								|| cartOrderProductDetail.getQty() < spec.getMinCountPerOrder()
								|| cartOrderProductDetail.getQty() > spec.getMaxCountPerOrder()) {
							if (sbMsg.toString().length() > 0) {
								sbMsg.append("、");
							}
							sbMsg.append(" < ");
							sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
									.append(">");
							mainProdNotEnough = true;
						}
					} else {
						sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName()).append(
								"-无数量资料!<BR/>");
					}
				} else if (StringUtils.equals("3", cartOrderProductDetail.getDetailTp())) {// 加购
					SpecificationInventory specificationInventory = new SpecificationInventory();
					CommonCriteria criteria = new CommonCriteria();
					criteria.addEq("productId", cartOrderProductDetail.getProdId());
					criteria.addEq("specId", Long.parseLong(cartOrderProductDetail.getProdSpecId()));
					int specInvSize = specificationinventoryDao.getListSize(criteria).intValue();
					if (specInvSize > 0) {
						specificationInventory = specificationinventoryDao.getSingle(criteria, null);
						int availableInventory = specificationInventory.getInventory();
						Specification spec = (Specification) baseMgr.get(Specification.class, Long.valueOf(cartOrderProductDetail
								.getProdSpecId()));
						// 找主商品的购物车数量
						CartOrderProduct cop = (CartOrderProduct) baseMgr.get(CartOrderProduct.class, cartOrderProductDetail
								.getCartOrderProdId());
						if (availableInventory <= 0 || availableInventory < cartOrderProductDetail.getQty()
								|| cartOrderProductDetail.getQty() < spec.getMinCountPerOrder()
								|| cartOrderProductDetail.getQty() > spec.getMaxCountPerOrder()
								|| cartOrderProductDetail.getQty() > cop.getQty()) {
							if (sbMsg.toString().length() > 0) {
								sbMsg.append("、");
							}
							sbMsg.append(" < ");
							sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
									.append(">");
							mainProdNotEnough = true;
						}
					} else {
						sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName()).append(
								"-无数量资料!<BR/>");
					}
				} else if (Arrays.asList("5", "6").contains(cartOrderProductDetail.getDetailTp())) {// 满额购,n選m
					SpecificationInventory specificationInventory = new SpecificationInventory();
					CommonCriteria criteria = new CommonCriteria();
					criteria.addEq("productId", cartOrderProductDetail.getProdId());
					criteria.addEq("specId", Long.parseLong(cartOrderProductDetail.getProdSpecId()));
					int specInvSize = specificationinventoryDao.getListSize(criteria).intValue();
					if (specInvSize > 0) {
						specificationInventory = specificationinventoryDao.getSingle(criteria, null);
						int availableInventory = specificationInventory.getInventory();
						if (availableInventory <= 0 || cartOrderProductDetail.getQty() > 1) {
							if (sbMsg.toString().length() > 0) {
								sbMsg.append("、");
							}
							sbMsg.append(" < ");
							sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
									.append(">");
							mainProdNotEnough = true;
						}
					} else {
						sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName()).append(
								"-无数量资料!<BR/>");
					}
				}
			}
		} else {
			sbMsg.append("无购物明细！");
		}
		// if (StringUtils.isNotBlank(addCmpPd)) {// 滿額購
		// SpecificationInventory specificationInventory = new SpecificationInventory();
		// CommonCriteria criteria = new CommonCriteria();
		// Product addProd = productService.get(addCmpPd.split(",")[0]);
		// Specification addSpec = productService.getSpecification(Long.parseLong(addCmpPd.split(",")[1]));
		// criteria.addEq("productId", addCmpPd.split(",")[0]);
		// criteria.addEq("specId", Long.parseLong(addCmpPd.split(",")[1]));
		// int specInvSize = specificationinventoryDao.getListSize(criteria).intValue();
		// if (specInvSize > 0) {
		// specificationInventory = specificationinventoryDao.getSingle(criteria, null);
		// int availableInventory = specificationInventory.getInventory();
		// if (availableInventory <= 0) {
		// if (sbMsg.toString().length() > 0) {
		// sbMsg.append("、");
		// }
		// sbMsg.append(" < ");
		// sbMsg.append(addProd.getProductName()).append(addSpec.getSpecificationName()).append(">");
		// mainProdNotEnough = true;
		// }
		// } else {
		// sbMsg.append(addProd.getProductName()).append(addSpec.getSpecificationName()).append("-无数量资料!<BR/>");
		// }
		// }

		// 贈品 (當主商品／滿額購都沒缺貨時檢查）
		if (!mainProdNotEnough) {
			if (cartOrderProductDetailList.size() > 0) {
				for (CartOrderProductDetail cartOrderProductDetail : cartOrderProductDetailList) {
					if (cartOrderProductDetail.getDetailTp().equals("2") && null != cartOrderProductDetail.getCartOrderProdId()) {// 赠品
						// 找主商品的购物车数量
						CartOrderProduct cop = (CartOrderProduct) baseMgr.get(CartOrderProduct.class, cartOrderProductDetail
								.getCartOrderProdId());
						SpecificationInventory specificationInventory = new SpecificationInventory();
						CommonCriteria criteria = new CommonCriteria();
						criteria.addEq("productId", cartOrderProductDetail.getProdId());
						criteria.addEq("specId", Long.parseLong(cartOrderProductDetail.getProdSpecId()));
						int specInvSize = specificationinventoryDao.getListSize(criteria).intValue();
						if (specInvSize > 0) {
							specificationInventory = specificationinventoryDao.getSingle(criteria, null);
							int availableInventory = specificationInventory.getInventory();
							if (availableInventory <= 0 || availableInventory < cartOrderProductDetail.getQty()
									|| cartOrderProductDetail.getQty() < cop.getQty()) {
								if (checkFlag.equals("step2")) {
									if (sbMsg.toString().length() > 0) {
										sbMsg.append("<br/>");
									}
									sbMsg.append("＜");
									sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
											.append("＞");
									if (availableInventory == 0) {
										sbMsg.append(":已送完");
									} else {
										sbMsg.append(":胜" + availableInventory + "件");
									}
								} else {
									if (sbMsg.toString().length() > 0) {
										sbMsg.append("、");
									}
									sbMsg.append("＜");
									sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
											.append("＞");
								}

							}
						} else {
							sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
									.append("-无数量资料!<BR/>");
						}
					} else if (cartOrderProductDetail.getDetailTp().equals("2")
							&& null == cartOrderProductDetail.getCartOrderProdId()) {// 活动赠品
						int availableInventory = Integer
								.parseInt(baseMgr
										.queryByHql(
												"select sum(availableInventory+cancelInventory-soldInventory) from SpecificationInventory where productId = ? ",
												new Object[] { cartOrderProductDetail.getProdId() })[0].toString());
						if (availableInventory <= 0) {
							if (checkFlag.equals("step2")) {
								if (sbMsg.toString().length() > 0) {
									sbMsg.append("<br/>");
								}
								sbMsg.append("＜");
								sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
										.append("＞");
								sbMsg.append(":已送完");
							} else {
								if (sbMsg.toString().length() > 0) {
									sbMsg.append("、");
								}
								sbMsg.append("＜");
								sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
										.append("＞");
							}
						}
					}
				}
			}
		}

		if (sbMsg.length() == 0) {
			sbMsg.append("OK");
		} else {
			StringBuffer tmpSbMsg = new StringBuffer();
			if (checkFlag.equals("step0")) {
				if (mainProdNotEnough) {
					tmpSbMsg.append(ServerValue.getMainStep0().replaceAll("＃＃＃", sbMsg.toString()));
				} else {
					tmpSbMsg.append(ServerValue.getPrtStep0().replaceAll("＃＃＃", sbMsg.toString()));
				}
			} else if (checkFlag.equals("step0Login")) {
				if (mainProdNotEnough) {
					tmpSbMsg.append(ServerValue.getMainloginStep0().replaceAll("＃＃＃", sbMsg.toString()));
				} else {
					tmpSbMsg.append(ServerValue.getPrtloginStep0().replaceAll("＃＃＃", sbMsg.toString()));
				}
			} else if (checkFlag.equals("step1")) {
				if (mainProdNotEnough) {
					tmpSbMsg.append(ServerValue.getMainStep1().replaceAll("＃＃＃", sbMsg.toString()));
				} else {
					tmpSbMsg.append(ServerValue.getPrtStep1().replaceAll("＃＃＃", sbMsg.toString()));
				}
			} else if (checkFlag.equals("step2")) {
				String rsPage = optional.get("rsPage");
				if (StringUtils.isNotBlank(rsPage)) {
					if (mainProdNotEnough) {
						if (StringUtils.equals("cart", rsPage)) {
							tmpSbMsg.append(ServerValue.getMainCartStep2().replaceAll("＃＃＃", sbMsg.toString()));
						} else if (StringUtils.equals("buy", rsPage)) {
							tmpSbMsg.append(ServerValue.getMainBuyStep2().replaceAll("＃＃＃", sbMsg.toString()));
						}
					} else {
						if (StringUtils.equals("cart", rsPage)) {
							tmpSbMsg.append(ServerValue.getPrtCartStep2().replaceAll("＃＃＃", sbMsg.toString()));
						} else if (StringUtils.equals("buy", rsPage)) {
							tmpSbMsg.append(ServerValue.getPrtBuyStep2().replaceAll("＃＃＃", sbMsg.toString()));
						}
					}
				}
			}
			sbMsg.setLength(0);
			sbMsg = tmpSbMsg;
		}
		return sbMsg.toString();
	}

	public String checkTuangouSpecInventory(String cartId) throws Exception {
		StringBuffer sbMsg = new StringBuffer();
		CartOrders cart = getTuangouCart(cartId);
		List<CartOrderProductDetail> cartOrderProductDetailList = new ArrayList<CartOrderProductDetail>();
		for (CartOrderProduct cop : cart.getCartOrderProducts()) {
			cartOrderProductDetailList.addAll(cop.getDetails());
		}
		if (cartOrderProductDetailList.size() > 0) {
			for (CartOrderProductDetail cartOrderProductDetail : cartOrderProductDetailList) {
				if (!Arrays.asList("2", "3", "5", "6").contains(cartOrderProductDetail.getDetailTp())) {// 不是赠品、加购、满额购
					SpecificationInventory specificationInventory = new SpecificationInventory();
					CommonCriteria criteria = new CommonCriteria();
					criteria.addEq("productId", cartOrderProductDetail.getProdId());
					criteria.addEq("specId", Long.parseLong(cartOrderProductDetail.getProdSpecId()));
					int specInvSize = specificationinventoryDao.getListSize(criteria).intValue();
					if (specInvSize > 0) {
						specificationInventory = specificationinventoryDao.getSingle(criteria, null);
						int availableInventory = specificationInventory.getInventory();
						Specification spec = (Specification) baseMgr.get(Specification.class, Long.valueOf(cartOrderProductDetail
								.getProdSpecId()));
						if (availableInventory <= 0 || availableInventory < cartOrderProductDetail.getQty()
								|| cartOrderProductDetail.getQty() < spec.getMinCountPerOrder()
								|| cartOrderProductDetail.getQty() > spec.getMaxCountPerOrder()) {
							if (sbMsg.toString().length() > 0) {
								sbMsg.append("、");
							}
							sbMsg.append(" < ");
							sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
									.append(">");
						}
					} else {
						sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName()).append(
								"-无数量资料!<BR/>");
					}
				}
			}
		} else {
			sbMsg.append("无购物明细！");
		}

		if (sbMsg.length() == 0) {
			sbMsg.append("OK");
		}
		return sbMsg.toString();
	}

	public String checkSpecInventoryBuyNowForPresent(String prodIdSpeId) throws Exception {
		StringBuffer sbMsg = new StringBuffer();
		String[] ayProIdSpeId = prodIdSpeId.split(";");
		if (ayProIdSpeId.length > 0) {
			for (int i = 0; i < ayProIdSpeId.length; i++) {
				SpecificationInventory specificationInventory = new SpecificationInventory();
				CommonCriteria criteria = new CommonCriteria();
				String[] ayInveny = ayProIdSpeId[i].split(",");
				if (ayInveny[3].equals("2")) {// 只查主商品，赠品不查
					criteria.addEq("productId", ayInveny[0]);
					criteria.addEq("specId", Long.parseLong(ayInveny[1]));
					int specInvSize = specificationinventoryDao.getListSize(criteria).intValue();
					Product product = productService.get(ayInveny[0]);
					if (specInvSize > 0) {
						specificationInventory = specificationinventoryDao.getSingle(criteria, null);
						int availableInventory = specificationInventory.getAvailableInventory()
								- specificationInventory.getSoldInventory() + specificationInventory.getCancelInventory();
						if (availableInventory <= 0 || availableInventory < Integer.parseInt(ayInveny[2])) {
							if (sbMsg.toString().length() > 0) {
								sbMsg.append("、");
							}
							sbMsg.append("＜");
							sbMsg.append(product.getProductName());
							sbMsg.append("＞");
						}
					} else {
						sbMsg.append(product.getProductName()).append("-无数量资料!\n");
					}
				}
			}
		} else {
			sbMsg.append("无购物明细！");
		}
		if (sbMsg.length() == 0) {
			sbMsg.append("OK");
		} else {
			StringBuffer tmpSbMsg = new StringBuffer();
			tmpSbMsg.append("很抱歉，赠品").append(sbMsg.toString()).append("为限量发送，目前库存数量不足。<BR/>请重新返回商品确认订购数量，再继续结帐。<BR/>");
			sbMsg.setLength(0);
			sbMsg = tmpSbMsg;
		}
		return sbMsg.toString();
	}

	public String checkSpecInventoryForPresent(String cartId, Map<String, String> optional) throws Exception {
		StringBuffer sbMsg = new StringBuffer();
		CartOrders cart = get(cartId);
		cart = this.calculateCart(cart, optional);
		List<CartOrderProductDetail> cartOrderProductDetailList = new ArrayList();
		for (CartOrderProduct cop : cart.getCartOrderProducts()) {
			cartOrderProductDetailList.addAll(cop.getDetails());
		}
		if (cartOrderProductDetailList.size() > 0) {
			for (CartOrderProductDetail cartOrderProductDetail : cartOrderProductDetailList) {
				if (cartOrderProductDetail.getDetailTp().equals("2")) {// 赠品
					SpecificationInventory specificationInventory = new SpecificationInventory();
					CommonCriteria criteria = new CommonCriteria();
					criteria.addEq("productId", cartOrderProductDetail.getProdId());
					criteria.addEq("specId", Long.parseLong(cartOrderProductDetail.getProdSpecId()));
					int specInvSize = specificationinventoryDao.getListSize(criteria).intValue();
					if (specInvSize > 0) {
						specificationInventory = specificationinventoryDao.getSingle(criteria, null);
						int availableInventory = specificationInventory.getAvailableInventory()
								- specificationInventory.getSoldInventory() + specificationInventory.getCancelInventory();
						if (availableInventory <= 0 || availableInventory < cartOrderProductDetail.getQty()) {
							if (sbMsg.toString().length() > 0) {
								sbMsg.append("、");
							}
							sbMsg.append("＜");
							sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
									.append("＞");
						}
					} else {
						sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName()).append(
								"-无数量资料!\n");
					}
				}
			}
		} else {
			sbMsg.append("无购物明细！");
		}
		if (sbMsg.length() == 0) {
			sbMsg.append("OK");
		} else {
			StringBuffer tmpSbMsg = new StringBuffer();
			tmpSbMsg.append("<b>提醒：</b>赠品  ").append(sbMsg.toString()).append(
					"为限量发送，目前库存数量不足。<BR/>如仍欲购买此商品，请按「我要继续结帐」；<BR/>欲修改主商品数量，请按「修改数量」。<BR/><BR/>");
			sbMsg.setLength(0);
			sbMsg = tmpSbMsg;
		}
		return sbMsg.toString();
	}

	public String checkSpecInventoryTwo(String cartId, String addCmpPd) throws Exception {
		StringBuffer sbMsg = new StringBuffer();
		CartOrders cart = get(cartId);
		List<CartOrderProductDetail> cartOrderProductDetailList = new ArrayList();
		for (CartOrderProduct cop : cart.getCartOrderProducts()) {
			cartOrderProductDetailList.addAll(cop.getDetails());
		}
		if (cartOrderProductDetailList.size() > 0) {
			for (CartOrderProductDetail cartOrderProductDetail : cartOrderProductDetailList) {
				if (!cartOrderProductDetail.getDetailTp().equals("2")) {// 不是赠品
					if (!cartOrderProductDetail.getProdSpecName().equals("N选M")) {// specName为N选M的不作确认
						SpecificationInventory specificationInventory = new SpecificationInventory();
						CommonCriteria criteria = new CommonCriteria();
						criteria.addEq("productId", cartOrderProductDetail.getProdId());
						criteria.addEq("specId", Long.parseLong(cartOrderProductDetail.getProdSpecId()));
						int specInvSize = specificationinventoryDao.getListSize(criteria).intValue();
						if (specInvSize > 0) {
							specificationInventory = specificationinventoryDao.getSingle(criteria, null);
							int availableInventory = specificationInventory.getAvailableInventory()
									- specificationInventory.getSoldInventory() + specificationInventory.getCancelInventory();
							if (availableInventory <= 0 || availableInventory < cartOrderProductDetail.getQty()) {
								if (sbMsg.toString().length() > 0) {
									sbMsg.append("、");
								}
								sbMsg.append("＜");
								sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
										.append("＞");
							}
						} else {
							sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
									.append("-无数量资料!<BR/>");
						}
					}
				}

			}
		} else {
			sbMsg.append("无购物明细！");
		}
		if (StringUtils.isNotBlank(addCmpPd)) {// 滿額購
			SpecificationInventory specificationInventory = new SpecificationInventory();
			CommonCriteria criteria = new CommonCriteria();
			Product addProd = productService.get(addCmpPd.split(",")[0]);
			Specification addSpec = productService.getSpecification(Long.parseLong(addCmpPd.split(",")[1]));
			criteria.addEq("productId", addCmpPd.split(",")[0]);
			criteria.addEq("specId", Long.parseLong(addCmpPd.split(",")[1]));
			int specInvSize = specificationinventoryDao.getListSize(criteria).intValue();
			if (specInvSize > 0) {
				specificationInventory = specificationinventoryDao.getSingle(criteria, null);
				int availableInventory = specificationInventory.getAvailableInventory()
						- specificationInventory.getSoldInventory() + specificationInventory.getCancelInventory();
				if (availableInventory <= 0) {
					if (sbMsg.toString().length() > 0) {
						sbMsg.append("、");
					}
					sbMsg.append("＜");
					sbMsg.append(addProd.getProductName()).append(addSpec.getSpecificationName()).append("＞");
				}
			} else {
				sbMsg.append(addProd.getProductName()).append(addSpec.getSpecificationName()).append("-无数量资料!<BR/>");
			}
		}
		if (sbMsg.length() == 0) {
			sbMsg.append("OK");
		} else {
			StringBuffer tmpSbMsg = new StringBuffer();
			tmpSbMsg.append("很抱歉，商品").append(sbMsg.toString()).append("库存数量不足！<BR/>请重新返回购物车确认订购数量，再继续结帐。<BR/>");
			sbMsg.setLength(0);
			sbMsg = tmpSbMsg;
		}
		return sbMsg.toString();
	}

	public String checkSpecInventoryTwoForPresent(String cartId, Map<String, String> optional) throws Exception {
		StringBuffer sbMsg = new StringBuffer();
		CartOrders cart = get(cartId);
		cart = this.calculateCart(cart, optional);
		List<CartOrderProductDetail> cartOrderProductDetailList = new ArrayList();
		for (CartOrderProduct cop : cart.getCartOrderProducts()) {
			cartOrderProductDetailList.addAll(cop.getDetails());
		}
		if (cartOrderProductDetailList.size() > 0) {
			for (CartOrderProductDetail cartOrderProductDetail : cartOrderProductDetailList) {
				if (cartOrderProductDetail.getDetailTp().equals("2")) {// 赠品
					SpecificationInventory specificationInventory = new SpecificationInventory();
					CommonCriteria criteria = new CommonCriteria();
					criteria.addEq("productId", cartOrderProductDetail.getProdId());
					criteria.addEq("specId", Long.parseLong(cartOrderProductDetail.getProdSpecId()));
					int specInvSize = specificationinventoryDao.getListSize(criteria).intValue();
					if (specInvSize > 0) {
						specificationInventory = specificationinventoryDao.getSingle(criteria, null);
						int availableInventory = specificationInventory.getAvailableInventory()
								- specificationInventory.getSoldInventory() + specificationInventory.getCancelInventory();
						if (availableInventory <= 0 || availableInventory < cartOrderProductDetail.getQty()) {
							if (sbMsg.toString().length() > 0) {
								sbMsg.append("、");
							}
							sbMsg.append("＜");
							sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName())
									.append("＞");
						}
					} else {
						sbMsg.append(cartOrderProductDetail.getProdName()).append(cartOrderProductDetail.getProdSpecName()).append(
								"-无数量资料!\n");
					}
				}
			}
		} else {
			sbMsg.append("无购物明细！");
		}
		if (sbMsg.length() == 0) {
			sbMsg.append("OK");
		} else {
			StringBuffer tmpSbMsg = new StringBuffer();
			tmpSbMsg.append("很抱歉，赠品").append(sbMsg.toString()).append("为限量发送，目前库存数量不足。<BR/>请重新返回购物车确认订购数量，再继续结帐。<BR/>");
			sbMsg.setLength(0);
			sbMsg = tmpSbMsg;
		}
		return sbMsg.toString();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.shopping.service.CartOrdersService#cleanCartOrder30Days(java.lang.String)
	 */
	@Transactional(readOnly = false)
	public void cleanCartOrder30Days(String cartId) throws Exception {
		CartOrders co = (CartOrders) baseMgr.get(CartOrders.class, cartId);
		Calendar lastMonth = Calendar.getInstance();
		lastMonth.add(Calendar.DAY_OF_MONTH, -30);
		DetachedCriteria dc = DetachedCriteria.forClass(CartOrders.class);
		dc.add(Restrictions.le("createDate", lastMonth.getTime()));

		if (co != null) {
			baseMgr.executeHql("delete from CartOrderProductDetail where cartId=?", new Object[] { co.getCartId() });
			baseMgr.executeHql("delete from CartOrderProduct where cartId=?", new Object[] { co.getCartId() });

			delete(co);
		}
	}

	@Transactional(readOnly = false)
	public void cleanCartOrderNow(String cartId) throws Exception {
		CartOrders co = (CartOrders) baseMgr.get(CartOrders.class, cartId);
		if (co != null) {
			baseMgr.executeHql("delete from CartOrderProductDetail where cartId=?", new Object[] { co.getCartId() });
			baseMgr.executeHql("delete from CartOrderProduct where cartId=?", new Object[] { co.getCartId() });

			delete(co);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.shopping.service.CartOrdersService#createCart(java.lang.String, java.lang.String,
	 * java.lang.String, java.lang.Long, int, java.lang.String, java.util.List)
	 */
	private CartOrders createCartBase(String memberId, String productId, List<String> productOption, Long specId,
			int qty, String categoryPath, List<String> addOnProductId) throws CoreException {
		CartOrders cart = new CartOrders();
		if (StringUtils.isNotBlank(memberId)) {
			// 耶客手機
			if (memberId.split("_").length > 1 && memberId.split("_")[1].equals("yekmobile")) {
				Member member = memberService.get(memberId.split("_")[0]);
				cart.setCartId(memberId);
				cart.setMemberId(memberId.split("_")[0]);
				cart.setMemberName(StringUtils.defaultIfEmpty(member.getName(), member.getLoginId()));
				cart.setLoginId(member.getLoginId());
				cart.setReceiverEmail(member.getSendEmail());
			} else {
				Member member = memberService.get(memberId);
				if (get(memberId) == null) {
					// 若 memberId 為 cartId 不存在, 表示主購物車不存在, 設 cartId 為 memberId
					cart.setCartId(memberId);
				}
				cart.setMemberId(memberId);
				cart.setMemberName(StringUtils.defaultIfEmpty(member.getName(), member.getLoginId()));
				cart.setLoginId(member.getLoginId());
				cart.setReceiverEmail(member.getSendEmail());
			}
		}
		// 若 cartId 為 null, 表示為主購物車存在, 應當為直接購買等. 給予一 UUID 為 cartId
		if (StringUtils.isBlank(cart.getCartId())) {
			cart.setCartId(java.util.UUID.randomUUID().toString());
		}
		cart.setOrderDt(DateUtil.getCurrentTime());
		cart.setChannelSeq(0);
		cart.setChannel("yaodian100.com"); // ?!
		cart = save(cart);

		// if (StringUtils.isNotBlank(productId)) {
		// cart = addProduct(memberId, cart.getCartId(), productId, productOption, specId, qty, categoryPath,
		// addOnProductId);
		// }
		return cart;
	}

	@Transactional(readOnly = false)
	public CartOrders createCartForStep1(String memberId, String productId, List<String> productOption, Long specId,
			int qty, String categoryPath, List<String> addOnProductId) throws CoreException {
		CartOrders cart = createCartBase(memberId, productId, productOption, specId, qty, categoryPath, addOnProductId);

		if (StringUtils.isNotBlank(productId)) {
			cart = addProductForStep1(memberId, cart.getCartId(), productId, productOption, specId, qty, categoryPath,
					addOnProductId);
		}
		return cart;
	}

	@Transactional(readOnly = false)
	public CartOrders createCart(String memberId, String productId, List<String> productOption, Long specId, int qty,
			String categoryPath, List<String> addOnProductId) throws CoreException {
		CartOrders cart = createCartBase(memberId, productId, productOption, specId, qty, categoryPath, addOnProductId);

		if (StringUtils.isNotBlank(productId)) {
			cart = addProduct(memberId, cart.getCartId(), productId, productOption, specId, qty, categoryPath, addOnProductId);
		}
		return cart;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.core.common.service.impl.DomainServiceImpl#get(java.io.Serializable)
	 */
	@Override
	@Transactional(readOnly = false)
	public CartOrders get(Serializable oid) throws CoreException {
		CartOrders cart = super.get(oid);
		if (cart != null) {
			Shelf shelf = null;
			Product product = null;
			Iterator<CartOrderProduct> prodIter = cart.getCartOrderProducts().iterator();
			while (prodIter.hasNext()) {
				CartOrderProduct cop = prodIter.next();
				// 商品類別: 0主商品 1預購, 2贈品, 3加購, 4活動, 5满额购, 6N選M
				shelf = shelfService.getActiveShelfByProductId(cop.getProdId());
				product = productService.get(cop.getProdId());
				boolean removeFlag = false;
				if (null == product || Arrays.asList("Y", "Q").contains(product.getIsDelete())) {
					// 商品主檔不存在
					logger.warn("商品主檔不存在, cartId:{}. productId:{}", cart.getCartId(), cop.getProdId());
					baseMgr.executeHql("delete from CartOrderProductDetail where cartOrderProdId=?", new Object[] { cop
							.getCartOrderProdId() });
					baseMgr.delete(cop);
					prodIter.remove();
				} else {
					cop.setIsScm(product.getIsScm());
					cop.setSupplierId(product.getSupplierId());

					int prodType = Integer.parseInt(cop.getProdTp());
					switch (prodType) {
					case 0:
					case 7:
						if (shelf == null) {
							// 一定會有上架檔
							logger.warn("Shelf不存在, cartId:{}. productId:{}", cart.getCartId(), cop.getProdId());
							removeFlag = true;
						}
						break;
					case 1:
						if (shelf == null) {
							// 一定會有上架檔
							logger.warn("Shelf不存在, cartId:{}. productId:{}", cart.getCartId(), cop.getProdId());
							removeFlag = true;
						}
						if (cart.getCartOrderProducts().size() > 1) {
							// 含預購商品不可合併結帳, *贈品?!
							logger.error("預購商品不可合併結帳, cartId:{}. product size:{}", cart.getCartId(), cart.getCartOrderProducts());
							removeFlag = true;
						}
						break;
					case 2: // 可能無上架檔
						if (cop.getQty() != 1) {
							// 檢核 N選M, 贈品 購買數量應為 1
							logger.error("贈品購買數量應為 1, cartId:{}. productId:{}, qty:{}", new Object[] { cart.getCartId(),
									cop.getProdId(), cop.getQty() });
							removeFlag = true;
						}
						break;
					case 3: // 無上架檔
						break;
					case 4:
						break;
					case 5:// 無上架檔
						// 滿額購不在活動效期
						CampaignProduct cp = campaignProductService.get(cop.getCampaignId());
						if (null != cp && cp.isEnable() && !cp.isDelete()) {
							Date now = DateUtil.getCurrentTime();
							if (!DateUtil.checkDateBetween(now, cp.getStartDateTime(), cp.getEndDateTime(), true, true)) {
								logger.warn("移除滿額購, cartId:{}. productId:{}, qty:{}", new Object[] { cart.getCartId(), cop.getProdId(),
										cop.getQty() });
								removeFlag = true;
							}
							// if (shelf == null) {
							// // 一定會有上架檔
							// logger.warn("滿額購Shelf不存在, cartId:{}. productId:{}", cart.getCartId(), cop.getProdId());
							// removeFlag = true;
							// }
							if (cart.getAmount().subtract(cop.getTotalPrice()).doubleValue() < cp.getMinOrderAmount().doubleValue()) {
								// 訂單金額未達滿額購標準
								logger.warn("訂單金額未達滿額購標準, cartId:{}. productId:{}", cart.getCartId(), cop.getProdId());
								removeFlag = true;
							}
						}

						break;
					case 6:
						if (shelf == null) {
							// 一定會有上架檔
							logger.warn("Shelf不存在, cartId:{}. productId:{}", cart.getCartId(), cop.getProdId());
							removeFlag = true;
						} else if (cop.getUnitPrice().compareTo(shelf.getShelfPrice()) != 0) {
							// 檢核 N選M 價格異動
							logger.warn("N選M價格異動, cartId:{}. productId:{}, price:{}", new Object[] { cart.getCartId(),
									cop.getProdId(), cop.getUnitPrice() });
							removeFlag = true;
						} else if (cop.getQty() != 1) {
							// 檢核 N選M, 贈品 購買數量應為 1
							logger.error("N選M數量應為 1, cartId:{}. productId:{}, qty:{}", new Object[] { cart.getCartId(),
									cop.getProdId(), cop.getQty() });
							removeFlag = true;
						} else if (cop.getDetails().size() != product.getPickupQty()) {
							// 檢核 N選M 的 detail size 應為 product.pickupQty
							logger.error("N選M數量不正確, cartId:{}. productId:{}, PickupQty:{}", new Object[] { cart.getCartId(),
									cop.getProdId(), product.getPickupQty() });
							removeFlag = true;
						} else {
							for (CartOrderProductDetail copd : cop.getDetails()) {
								if (copd.getQty() != 1) {
									// 檢核 N選M 的 detail qty 應為 1
									logger.error("N選M detail 數量不正確, cartId:{}. productId:{}, qty:{}", new Object[] { cart.getCartId(),
											copd.getProdId(), copd.getQty() });
									removeFlag = true;
								}
							}
						}
						break;
					}
					if (removeFlag) {
						baseMgr.executeHql("delete from CartOrderProductDetail where cartOrderProdId=?", new Object[] { cop
								.getCartOrderProdId() });
						baseMgr.delete(cop);
						prodIter.remove();
					} else {
						// 繼續檢核 detail
						Map<String, AddOnProduct> addOnMap = null;
						Iterator<CartOrderProductDetail> detailIter = cop.getDetails().iterator();
						while (detailIter.hasNext()) {
							CartOrderProductDetail copd = detailIter.next();
							// 贈品與加價檢核上下架日期
							if (Arrays.asList("2", "3").contains(copd.getDetailTp())) {
								if (addOnMap == null) {
									addOnMap = productService.getAddOnProducts(cop.getProdId(), false);
								}
								AddOnProduct addOn = addOnMap.get(copd.getProdId());
								if (addOn == null) {
									// 移除 getAddOnProducts(取得有效的加價與贈品) 沒有的加價與贈品
									detailIter.remove();
									continue;
								} else {
									if ("3".equals(copd.getDetailTp())) {
										copd.setAmount(addOn.getAddOnPrice());
									}
									if ("2".equals(copd.getDetailTp()) && !(addOn.getAddOnPrice().floatValue() == 0.0f)) {
										// 贈品變加價購
										detailIter.remove();
										continue;
									}
								}
							}
							if (copd.getProdId().equals(product.getProductId())) {
								copd.setWeight(product.getProductWeight());
								copd.setVendId(product.getSupplierId());
								copd.setEcCost(product.getProductCost());

								if ("3".equals(cop.getProdTp())) {
									// by pass
								} else if ("5".equals(cop.getProdTp())) {
									// for 满额购 金额再确认
									CampaignProduct cp = campaignProductService.get(cop.getCampaignId());
									cop.setUnitPrice(cp.getPrice());
								} else {
									cop.setUnitPrice(shelf.getShelfPrice());
								}
								if ("3".equals(copd.getDetailTp())) {
									// by pass
								} else if ("5".equals(copd.getDetailTp())) {
									copd.setAmount(cop.getUnitPrice());
								} else {
									copd.setAmount(shelf.getShelfPrice());
								}
							} else {
								Product p = productService.get(copd.getProdId());
								if (p != null) {
									copd.setWeight(p.getProductWeight());
									copd.setVendId(p.getSupplierId());
									copd.setEcCost(p.getProductCost());
								}
							}
						}
						cop.setEcCost(product.getProductCost());
						cop.setPmId(product.getPmID());
						cop.setPmGroup(product.getOrganizationPath());
					}
				}
			}

			// cart = new CartOrders();
			// cart = getDao().get(oid);
			// logger.info("cart:{}", cart.getCartOrderProducts().size());
			// 算商品數量(贈品&n選m的主商品不算)
			cart.setProductSum(getCartOrderProductDetailListSize(cart).intValue());
			cart.getAmount();
			cart.getWeightSum();
			cart.getMustPay();
		}
		return cart;
	}

	@Override
	@Transactional(readOnly = false)
	public CartOrders getTuangouCart(Serializable oid) throws CoreException {
		CartOrders cart = super.get(oid);
		if (cart != null) {
			ShelfTuangou shelfTuangou = null;
			Product product = null;
			Iterator<CartOrderProduct> prodIter = cart.getCartOrderProducts().iterator();
			while (prodIter.hasNext()) {
				CartOrderProduct cop = prodIter.next();
				// 商品類別: 0主商品 1預購, 2贈品, 3加購, 4活動, 5满额购, 6N選M
				shelfTuangou = shelfTuangouService.getActiveShelfTuangouByProductId(cop.getProdId());
				product = productService.get(cop.getProdId());
				boolean removeFlag = false;
				if (null == product || Arrays.asList("Y", "Q").contains(product.getIsDelete())) {
					// 商品主檔不存在
					logger.warn("商品主檔不存在, cartId:{}. productId:{}", cart.getCartId(), cop.getProdId());
					baseMgr.executeHql("delete from CartOrderProductDetail where cartOrderProdId=?", new Object[] { cop
							.getCartOrderProdId() });
					baseMgr.delete(cop);
					prodIter.remove();
				} else {
					cop.setIsScm(product.getIsScm());
					cop.setSupplierId(product.getSupplierId());

					int prodType = Integer.parseInt(cop.getProdTp());
					switch (prodType) {
					case 0:
					case 7:
						if (null == shelfTuangou) {
							// 一定會有上架檔
							logger.warn("shelfTuangou不存在, cartId:{}. productId:{}", cart.getCartId(), cop.getProdId());
							removeFlag = true;
						}
						break;
					case 1:
						if (shelfTuangou == null) {
							// 一定會有上架檔
							logger.warn("shelfTuangou不存在, cartId:{}. productId:{}", cart.getCartId(), cop.getProdId());
							removeFlag = true;
						}
						if (cart.getCartOrderProducts().size() > 1) {
							// 含預購商品不可合併結帳, *贈品?!
							logger.error("預購商品不可合併結帳, cartId:{}. product size:{}", cart.getCartId(), cart.getCartOrderProducts());
							removeFlag = true;
						}
						break;
					case 2:
					case 3: // 無上架檔
					case 4:
					case 5:// 無上架檔
					case 6:
						break;
					}
					if (removeFlag) {
						baseMgr.executeHql("delete from CartOrderProductDetail where cartOrderProdId=?", new Object[] { cop
								.getCartOrderProdId() });
						baseMgr.delete(cop);
						prodIter.remove();
					} else {
						// 繼續檢核 detail
						Iterator<CartOrderProductDetail> detailIter = cop.getDetails().iterator();
						while (detailIter.hasNext()) {
							CartOrderProductDetail copd = detailIter.next();
							if (copd.getProdId().equals(product.getProductId())) {
								copd.setWeight(product.getProductWeight());
								copd.setVendId(product.getSupplierId());
								copd.setEcCost(product.getProductCost());
								cop.setUnitPrice(shelfTuangou.getPrice());
								copd.setAmount(shelfTuangou.getPrice());
							} else {
								Product p = productService.get(copd.getProdId());
								if (p != null) {
									copd.setWeight(p.getProductWeight());
									copd.setVendId(p.getSupplierId());
									copd.setEcCost(p.getProductCost());
								}
							}
						}
						cop.setEcCost(product.getProductCost());
						cop.setPmId(product.getPmID());
						cop.setPmGroup(product.getOrganizationPath());
					}
				}
			}
			// 算商品數量(贈品&n選m的主商品不算)
			cart.setProductSum(getCartOrderProductDetailListSize(cart).intValue());
			cart.getAmount();
			cart.getWeightSum();
			cart.getMustPay();
		}
		return cart;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.shopping.service.CartOrdersService#getCart(java.lang.String, java.lang.String)
	 */
	@Override
	@Transactional(readOnly = false)
	public CartOrders getCart(String memberId, String cartId) throws CoreException {
		CartOrders cart = null;
		if (StringUtils.isNotBlank(cartId)) {
			cart = get(cartId);
		}
		if (cart == null && StringUtils.isNotBlank(memberId)) {
			cart = get(memberId);
		}

		if (cart != null) {
			if (StringUtils.isNotBlank(cart.getMemberId())) {
				if (!cart.getMemberId().equals(memberId)) {
					logger.error("memberId incorrect, cartId;{}, memberId;{}", cart.getCartId(), memberId);
					cart = null;
				}
			}
		}

		return cart;
	}

	/**
	 * 計算購買商品項數 (忽略N選M與贈品)
	 * 
	 * @param cartId
	 * @return
	 * @throws CoreException
	 */
	private Number getCartOrderProductDetailListSize(CartOrders cart) throws CoreException {
		/** detailTp, 0主商品 1預購, 2贈品 , 3加購, 4活動, 5满额购, 6N選M */
		List<String> detailTps = Arrays.asList("0", "1", "3", "4", "5", "6", "7");

		int i = 0;
		for (CartOrderProduct cop : cart.getCartOrderProducts()) {
			for (CartOrderProductDetail copd : cop.getDetails()) {
				if (detailTps.contains(copd.getDetailTp())) {
					i++;
				}
			}
		}
		return i;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.shopping.service.CartOrdersService#mergeCart(java.lang.String, java.lang.String)
	 */
	@Override
	@Transactional(readOnly = false)
	public CartOrders mergeCart(String cartFrom, String cartTo) throws CoreException {
		CartOrders cartObjTo = get(cartTo);
		Member member = memberService.get(cartObjTo.getMemberId());
		if (StringUtils.equalsIgnoreCase("nonmember", member.getApplySource())) {
			try {
				cleanCartOrderNow(member.getMemberId());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (cartObjTo != null) {
			CartOrders cartObjFrom = get(cartFrom);
			List<String> prodIds = new ArrayList<String>();
			for (CartOrderProduct cop : cartObjTo.getCartOrderProducts()) {
				// 紀錄原有商品代碼
				prodIds.add(cop.getProdId());
			}
			if (cartObjFrom != null) {
				for (CartOrderProduct cop : cartObjFrom.getCartOrderProducts()) {
					if (!prodIds.contains(cop.getProdId())) {
						// 若原有購物車無該商品, 才 merge
						for (CartOrderProductDetail copd : cop.getDetails()) {
							copd.setCart(cartObjTo);
						}
						cartObjTo.addCartOrderProduct(cop);
					}
				}
				cartObjFrom.setCartOrderProducts(new ArrayList());
				save(cartObjTo);
				delete(cartObjFrom);
			} else {
				logger.warn("cartFrom({}) is null, skip. cartTo({})", cartFrom, cartTo);
			}
		} else {
			logger.warn("cartTo({}) is null, skip. cartFrom({})", cartTo, cartFrom);
		}
		return get(cartTo);
	}

	@Transactional(readOnly = false)
	public CartOrders processCartOrder(String memberId, String[] itemNo, String[] specNo, String[] qty,
			String[] categoryPath, String[] type, String presents, String addOns, String cartId) throws Exception {
		CartOrders entity = null;
		if (null != itemNo) {// 判斷有無prodid
			// ArrayList<CartOrderProduct> orderProdList = new ArrayList<CartOrderProduct>();
			// ArrayList<CartOrderProductDetail> orderDetailList = new ArrayList<CartOrderProductDetail>();
			// 抓商品資料
			Product product = null;
			product = productService.get(itemNo[0]);
			if (product == null) {
				throw new CoreException("商品不存在");
			} else if (product.getProductType() == 1 || product.getProductType() == 2 || product.getProductType() == 3) {
				throw new CoreException("商品型态不符，不允许直接加入购物车");
			}
			if (StringUtils.isNotBlank(cartId)) {
				entity = get(cartId);
			}
			if (entity == null) {
				entity = new CartOrders();
			}
			entity.setChannel("");
			entity.setChannelSeq(0);
			entity.setClientIp("");
			if (StringUtils.isNotBlank(memberId)) {
				Member member = memberService.get(memberId);
				entity.setMemberId(member.getMemberId());
				entity.setMemberName(member.getLoginId());
				// entity.setCartId(cartOrders.getCartId());
				if (StringUtils.isBlank(entity.getCartId())) {
					entity.setCartId(memberId);
				}
			} else {
				entity.setMemberId(" ");
				entity.setMemberName(" ");
			}
			if (StringUtils.isBlank(entity.getCartId())) {
				entity.setCartId(java.util.UUID.randomUUID().toString());
			}
			entity.setLoginId("");
			entity.setMemo("");
			entity.setOrderDt(new Date());
			entity.setReceiverAddr("");
			entity.setReceiverArea("");
			entity.setReceiverCity("");
			entity.setReceiverEmail("");
			entity.setReceiverExt("");
			entity.setReceiverMobile("");
			entity.setReceiverName("");
			entity.setReceiverPhone("");
			entity.setReceiverPhoneArea("");
			entity.setReceiverProvince("");
			entity.setReceiverTp("");
			entity.setReceiverZip("");
			entity.setBenefit(new BigDecimal(0));
			int prodSeq = 1;
			int detailSeq = 1;
			Shelf shelf = null;

			Specification specification = null;
			List<Specification> specificationList = null;
			for (int i = 0; i < itemNo.length; i++) {
				// orderDetailList = new ArrayList<CartOrderProductDetail>();
				CartOrderProduct entityProd = new CartOrderProduct();
				entityProd.setCampaignId("");
				entityProd.setCampaignName("");
				entityProd.setCampaign(false);
				Category cg = categoryService.get(Long.parseLong(categoryPath[i]));
				entityProd.setCategoryPath(cg.getCategoryPath());
				entityProd.setCreateDate(new Date());
				entityProd.setCreateUser("");
				entityProd.setLogisticSt("");
				entityProd.setLogisticTp("");
				entityProd.setPmGroup("");
				entityProd.setPmId("");

				entityProd.setProdId(product.getProductId());
				entityProd.setProdName(product.getProductName());
				entityProd.setProdSeq(prodSeq);

				// 抓spec資料
				CommonCriteria crit = new CommonCriteria();
				crit.addEq("specificationId", Long.parseLong(specNo[i]));
				crit.addEq("isDelete", "N");
				specification = productService.getSpecificationList(0, 1, crit, null).get(0);
				if (specification == null) {
					throw new CoreException("商品规格不存在");
				}
				entityProd.setProdSpecId(specification.getSpecificationId().toString());
				entityProd.setProdSpecName(specification.getSpecificationName());
				shelf = shelfService.getActiveShelfByProductId(itemNo[i]);

				if (type[i].equals("6")) {
					entityProd.setProdTp("6N");
				} else {
					entityProd.setProdTp(type[i]);
				}
				entityProd.setReturn(false);
				entityProd.setChange(false);
				entityProd.setDiscount(new BigDecimal(0.00));
				entityProd.setErpCost(new BigDecimal(0.00));
				entityProd.setEcCost(new BigDecimal(0.00));
				entityProd.setQty(Integer.valueOf(qty[i]));
				entityProd.setUnitPrice(shelf.getShelfPrice());
				entity.addCartOrderProduct(entityProd);

				// 寫入detail資料
				crit = new CommonCriteria();
				crit.addEq("productId", itemNo[i]);
				crit.addEq("isDelete", "N");
				String[] sortShowSeq = { "showSeq desc" };
				specificationList = productService.getSpecificationList(0, -1, crit, sortShowSeq);
				for (int j = 0; j < specificationList.size(); j++) {
					Specification spec = specificationList.get(j);
					CartOrderProductDetail entityDetail = new CartOrderProductDetail();
					entityDetail.setAmount(shelf.getShelfPrice());
					entityDetail.setErpCost(new BigDecimal(0.00));
					entityDetail.setEcCost(new BigDecimal(0.00));

					entityDetail.setProdSeq(prodSeq);
					// for N選M的主商品
					if (detailSeq == 1 && type[i].equals("6")) {
						entityDetail.setDetailTp("6N");
					} else {
						entityDetail.setDetailTp(type[i]);
					}
					entityDetail.setProdId(product.getProductId());
					entityDetail.setProdName(product.getProductName());
					entityDetail.setProdSpecId(spec.getSpecificationId().toString());
					entityDetail.setProdSpecName(spec.getSpecificationName());
					if (String.valueOf(spec.getSpecificationId()).equals(specNo[i])) {
						entityDetail.setQty(Integer.valueOf(qty[i]));
					} else {
						entityDetail.setQty(Integer.valueOf(0));
					}
					entityDetail.setVendId("");
					// orderDetailList.add(entityDetail);
					entityProd.addDetail(entityDetail);
					detailSeq++;
				}

				prodSeq++;
				// entityProd.setCartOrderProductDetail(orderDetailList);
				// orderProdList.add(entityProd);
				entity.setMyWallet(new BigDecimal(0));
				entity.setBonus(new BigDecimal(0));
				entity.setBenefit(new BigDecimal(0));
				entity.setCoupon(new BigDecimal(0));
				entity.setCash(new BigDecimal(0));
				entity.setDiscount(new BigDecimal(0));
				entity.setShipfare(new BigDecimal(0));
				entity.setAmount(new BigDecimal(0));
				entity.setMustPay(entity.getAmount().add(entity.getShipfare()).subtract(entity.getBonus()).subtract(
						entity.getBenefit()).subtract(entity.getMyWallet()));

				// CartOrders cartOrders;

				/* 贈品 */
				// logger.info("getPresents():{}", getPresents());
				if (!presents.equals("null")) {
					JSONArray jsonObject = JSONArray.fromObject(presents);
					// logger.info("jsonObject.size():{}", jsonObject.size());
					for (int ii = 0; ii < jsonObject.size(); ii++) {
						JSONObject jsonObject2 = (JSONObject) jsonObject.get(ii);
						CartOrderProductDetail entityDetail = new CartOrderProductDetail();
						entityDetail.setAmount(new BigDecimal(0.00));
						entityDetail.setErpCost(new BigDecimal(0.00));
						entityDetail.setEcCost(new BigDecimal(0.00));

						entityDetail.setDetailTp(String.valueOf(jsonObject2.get("type")));
						Product ptProduct = productService.get(String.valueOf(jsonObject2.get("itemNo")));
						entityDetail.setProdId(ptProduct.getProductId());
						entityDetail.setProdName(ptProduct.getProductName());
						crit = new CommonCriteria();
						crit.addEq("productId", String.valueOf(jsonObject2.get("itemNo")));
						crit.addEq("specificationId", Long.parseLong(String.valueOf(jsonObject2.get("specNo"))));
						crit.addEq("isDelete", "N");
						// logger.info("spec.size():{}", productService.getSpecificationList(0, -1, crit, null).size());
						if (productService.getSpecificationList(0, -1, crit, null).size() > 0) {
							Specification ptSpec = productService.getSpecificationList(0, -1, crit, null).get(0);
							entityDetail.setProdSpecId(ptSpec.getSpecificationId().toString());
							entityDetail.setProdSpecName(ptSpec.getSpecificationName());
							entityDetail.setQty(Integer.valueOf(String.valueOf(jsonObject2.get("qty"))));
							entityDetail.setVendId("");
							// orderDetailList.add(entityDetail);
							detailSeq++;
						}
						entityProd.addDetail(entityDetail);
					}
				}
				/* 加購 */
				// logger.info("addOns():{}", addOns);
				if (!addOns.equals("null")) {
					JSONArray jsonObject = JSONArray.fromObject(addOns);
					CartOrderProductDetail entityDetail = null;
					for (int ii = 0; ii < jsonObject.size(); ii++) {
						JSONObject jsonObject2 = (JSONObject) jsonObject.get(ii);
						if (StringUtils.equals(jsonObject2.get("type").toString(), "6")) {
							crit = new CommonCriteria();
							crit.addEq("productId", jsonObject2.get("itemNo").toString());
							crit.addEq("isDelete", "N");
							specificationList = productService.getSpecificationList(0, -1, crit, sortShowSeq);
							for (int j = 0; j < specificationList.size(); j++) {
								Specification spec = specificationList.get(j);
								entityDetail = new CartOrderProductDetail();

								entityDetail.setAmount(new BigDecimal(0.00));
								entityDetail.setErpCost(new BigDecimal(0.00));
								entityDetail.setEcCost(new BigDecimal(0.00));
								Product ptProduct = productService.get(spec.getProductId());
								entityDetail.setDetailTp(type[i]);
								entityDetail.setProdId(ptProduct.getProductId());
								entityDetail.setProdName(ptProduct.getProductName());
								entityDetail.setProdSpecId(spec.getSpecificationId().toString());
								entityDetail.setProdSpecName(spec.getSpecificationName());
								if (String.valueOf(spec.getSpecificationId()).equals(jsonObject2.get("specNo").toString())) {
									entityDetail.setQty(Integer.valueOf(qty[i]));
								} else {
									entityDetail.setQty(Integer.valueOf(0));
								}
								entityDetail.setVendId("");
								// orderDetailList.add(entityDetail);
								entityProd.addDetail(entityDetail);
								detailSeq++;
							}
						} else {
							entityDetail = new CartOrderProductDetail();

							entityDetail.setAmount(new BigDecimal(0.00));
							entityDetail.setErpCost(new BigDecimal(0.00));
							entityDetail.setEcCost(new BigDecimal(0.00));

							entityDetail.setDetailTp(String.valueOf(jsonObject2.get("type")));
							Product ptProduct = productService.get(String.valueOf(jsonObject2.get("itemNo")));
							entityDetail.setProdId(ptProduct.getProductId());
							entityDetail.setProdName(ptProduct.getProductName());
							crit = new CommonCriteria();
							crit.addEq("productId", String.valueOf(jsonObject2.get("itemNo")));
							crit.addEq("specificationId", Long.parseLong(String.valueOf(jsonObject2.get("specNo"))));
							crit.addEq("isDelete", "N");
							if (productService.getSpecificationList(0, -1, crit, null).size() > 0) {
								Specification ptSpec = productService.getSpecificationList(0, -1, crit, null).get(0);
								entityDetail.setProdSpecId(ptSpec.getSpecificationId().toString());
								entityDetail.setProdSpecName(ptSpec.getSpecificationName());
								entityDetail.setQty(Integer.valueOf(String.valueOf(jsonObject2.get("qty"))));
								entityDetail.setVendId("");
								// orderDetailList.add(entityDetail);
								detailSeq++;
							}
							entityProd.addDetail(entityDetail);
						}
					}
				}
				// logger.info("xxxxxxxxxxxxxxxxxcartId:{}", cartId);
				save(entity);
				// if (StringUtils.isNotBlank(cartId)) {// 如果cartId不為空,就新增至相同的cartId
				// entity = getCartOrdersByCartOrderId(cartId);
				// cartOrders = saveSameCartOrders(entity, orderProdList, orderDetailList);
				// } else {
				// cartOrders = saveCartOrders(entity, orderProdList, orderDetailList);
				// }
			}
			itemNo = null;
		} else {
			logger.info("null == itemNo");
		}
		return entity;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.core.common.service.impl.DomainServiceImpl#save(java.lang.Object)
	 */
	@Override
	@Transactional(readOnly = false, timeout = 5)
	public CartOrders save(CartOrders entity) throws CoreException {
		// List<String> pIds = new ArrayList<String>();
		// Iterator<CartOrderProduct> it = entity.getCartOrderProducts().iterator();
		// while (it.hasNext()) {
		// CartOrderProduct cop = it.next();
		// if (pIds.contains(cop.getProdId())) {
		// logger.warn("remove duplication cop, cartId:{}, prodId:{}", entity.getCartId(), cop.getProdId());
		// it.remove();
		// } else {
		// pIds.add(cop.getProdId());
		// cop.getTotalPrice();
		// }
		// }
		// entity.getAmount();
		// entity.getMustPay();
		return super.save(entity);
	}

	/**
	 * @param cartOrderProductDetailDao the cartOrderProductDetailDao to set
	 */
	public void setCartOrderProductDetailDao(ObjectDao<CartOrderProductDetail> cartOrderProductDetailDao) {
		this.cartOrderProductDetailDao = cartOrderProductDetailDao;
	}

	/**
	 * @param specificationinventoryDao the specificationinventoryDao to set
	 */
	public void setSpecificationinventoryDao(SpecificationInventoryDao specificationinventoryDao) {
		this.specificationinventoryDao = specificationinventoryDao;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seecom.yaodian100.ec.shopping.service.CartOrdersService#showDetailWeight(com.yaodian100.core.common.dao.impl.
	 * CommonCriteria)
	 */
	@Override
	public Map<String, String> showProductWeight(List<CartOrderProductDetail> cartOrderProductDetails) throws Exception {
		// logger.info("cartOrderProductDetails size:{}", cartOrderProductDetails.size());
		BigDecimal totalWeight = new BigDecimal(0);
		Map<String, String> resultMap = new HashMap<String, String>();
		if (cartOrderProductDetails.size() > 0) {
			for (CartOrderProductDetail cartOrderProductDetail : cartOrderProductDetails) {
				Product product = productService.get(cartOrderProductDetail.getProdId());
				if (product.getProductWeight().compareTo(new BigDecimal(0.00)) == 1) {
					totalWeight = totalWeight.add(product.getProductWeight().multiply(
							new BigDecimal(cartOrderProductDetail.getQty())));
				}
				resultMap.put(cartOrderProductDetail.getDetailTp() + "," + cartOrderProductDetail.getProdId(), product
						.getProductWeight().intValue() > 0 ? product.getProductWeight().divide(new BigDecimal(1000), 3, 0)
						.toString() : "0.000");
			}
		}
		// 小数点第三位后无条件进位
		resultMap.put("totalWeight", totalWeight.divide(new BigDecimal(1000), 3, 0).toString());
		return resultMap;
	}

	public int checkSpecInvReturnQty(Product product, Specification spec, SpecificationInventory specInv, int qty)
			throws Exception {
		if (product.getProductType() == 0 || product.getProductType() == 7 || product.getProductType() == 1) {
			if (!(qty <= spec.getMaxCountPerOrder() && qty >= spec.getMinCountPerOrder() && qty <= specInv.getInventory())) {
				qty = spec.getMaxCountPerOrder();
			}
		}
		if (product.getProductType() == 2) {
			if (!(qty <= specInv.getInventory())) {
				qty = spec.getMaxCountPerOrder();
			}
		}
		if (product.getProductType() == 3) {
			if (!(qty <= spec.getMaxCountPerOrder() && qty >= spec.getMinCountPerOrder() && qty <= specInv.getInventory())) {
				qty = spec.getMaxCountPerOrder();
			}
		}
		if (product.getProductType() == 6) {
			qty = 1;
		}
		if (product.getProductType() == 5) {
			if (!(qty == 1 && qty <= specInv.getInventory())) {
				qty = 1;
			}
		}
		return qty;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.core.common.service.impl.DomainServiceImpl#delete(java.lang.Object)
	 */
	@Override
	@Transactional(readOnly = false, timeout = 5)
	public void delete(CartOrders entity) throws CoreException {
		baseMgr.executeHql("delete from CartOrderProductDetail where cartId=?", new Object[] { entity.getCartId() });
		baseMgr.executeHql("delete from CartOrderProduct where cartId=?", new Object[] { entity.getCartId() });
		baseMgr.executeHql("delete from CartOrders where cartId=?", new Object[] { entity.getCartId() });
		// super.delete(entity);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.core.common.service.impl.DomainServiceImpl#update(java.lang.Object)
	 */
	@Override
	@Transactional(readOnly = false, timeout = 5)
	public CartOrders update(CartOrders entity) throws CoreException {
		return super.update(entity);
	}

	@Transactional(readOnly = false)
	public CartOrders forceUpdateCart(CartOrders entity) throws CoreException {
		if (entity != null && entity.getCartOrderProducts() != null) {
			Date now = DateUtil.getCurrentTime();
			// 檢查商品是否已下架(主商品／n選m／精品)
			for (CartOrderProduct cop : entity.getCartOrderProducts()) {
				if (Arrays.asList("0", "6", "7").contains(cop.getProdTp())) {
					Date currentDate = new Date();
					Object[] shelfs = baseMgr.queryByHql(
							"from Shelf where productId=? and startDate<? and endDate>? and shelfStatus=?", new Object[] {
									cop.getProdId(), currentDate, currentDate, "SHF500" }, 0, 1);
					if (shelfs == null || shelfs.length == 0) {
						// 自購物車移除
						baseMgr.executeHql("delete from CartOrderProductDetail where cartOrderProductId=?", new Object[] { cop
								.getCartOrderProdId() });
						baseMgr.delete(cop);
						entity.getCartOrderProducts().remove(cop);
						// 移掉cartOrderProduct後直接到下一個cartOrderProduct
						continue;
					}
				}
				// 檢查商品是否已下架(满额购)
				if ("5".equals(cop.getProdTp())) {
					CampaignProduct cp = campaignProductService.getProduct(cop.getProdId());
					if (null == cp || !DateUtil.checkDateBetween(now, cp.getStartDateTime(), cp.getEndDateTime(), true, true)) {
						// 自購物車移除
						baseMgr.executeHql("delete from CartOrderProductDetail where cartOrderProductId=?", new Object[] { cop
								.getCartOrderProdId() });
						baseMgr.delete(cop);
						entity.getCartOrderProducts().remove(cop);
						// 移掉cartOrderProduct後直接到下一個cartOrderProduct
						continue;
					}
				}

				for (CartOrderProductDetail copd : cop.getDetails()) {
					// 檢查detail是否已下架
					if (copd.getDetailTp().equals("3")) {
						Object[] tmpCops = baseMgr.queryByHql("select prodId from CartOrderProduct where cartOrderProdId = ?",
								new Object[] { copd.getCartOrderProdId() });
						if (null != tmpCops) {
							Date currentDate = new Date();
							Object[] adps = baseMgr
									.queryByHql(
											"from AddOnProduct where addOnPrice > ? and isEnable=? and isDelete!=? and startDate <=? and endDate >=? and addOnProductId=? and mainProductId = ?",
											new Object[] { Integer.valueOf(0), "Y", "Y", currentDate, currentDate, copd.getProdId(),
													tmpCops[0] });
							if (null == adps || adps.length == 0) {
								baseMgr.delete(copd);
								cop.getDetails().remove(copd);
							}
						}
					}
				}
				// end of 檢查商品是否已下架
			}

			for (CartOrderProduct cop : entity.getCartOrderProducts()) {

				// Product level
				Object[] results = baseMgr.queryByHql("from SpecificationInventory where specId=?", new Object[] { Long
						.valueOf(cop.getProdSpecId()) }, 0, 1);
				SpecificationInventory mainSi = null;
				Specification mainSpec = null;
				if (!cop.getProdTp().equals("6")) {
					mainSi = (SpecificationInventory) results[0];
					mainSpec = (Specification) baseMgr.get(Specification.class, Long.valueOf(cop.getProdSpecId()));
				}
				if (mainSi != null && mainSi.getInventory() < cop.getQty()) {
					// 库存小于购物车数量
					if (mainSi.getInventory() < mainSpec.getMaxCountPerOrder()) {
						cop.setQty(mainSi.getInventory());
					} else {
						cop.setQty(mainSpec.getMaxCountPerOrder());
					}

					if (mainSi.getInventory() < mainSpec.getMinCountPerOrder()) {
						cop.setQty(0);
					}
					baseMgr.update(cop);
				}
				boolean needToSetZeroToCop = false;
				for (CartOrderProductDetail copd : cop.getDetails()) {

					boolean needToUpdate = false;
					if (cop.getQty() == 0) {
						copd.setQty(0);
						needToUpdate = true;
					} else {
						SpecificationInventory detailSi = (SpecificationInventory) (baseMgr
								.queryByHql("from SpecificationInventory where specId=?", new Object[] { Long.valueOf(copd
										.getProdSpecId()) }, 0, 1)[0]);
						if (cop.getQty() < copd.getQty()) {
							copd.setQty(cop.getQty());
							needToUpdate = true;
						}
						if (detailSi.getInventory() < copd.getQty()) {
							copd.setQty(detailSi.getInventory());
							needToUpdate = true;
						}
						if (cop.getQty() > 0 && copd.getQty() == 0) {
							copd.setQty(cop.getQty());
							needToUpdate = true;
						}
						if (copd.getDetailTp().equals("6") && copd.getQty() == 0) {
							needToSetZeroToCop = true;
						}
					}
					if (needToUpdate) {
						baseMgr.update(copd);
					}
				}
				if (needToSetZeroToCop) {
					cop.setQty(0);
					for (CartOrderProductDetail copd : cop.getDetails()) {
						copd.setQty(0);
						baseMgr.update(copd);
					}
					baseMgr.update(cop);
				}
			}
		}
		return entity;
	}

	public TimeLimitSaleService getTimeLimitSaleService() {
		return timeLimitSaleService;
	}

	public void setTimeLimitSaleService(TimeLimitSaleService timeLimitSaleService) {
		this.timeLimitSaleService = timeLimitSaleService;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.shopping.service.CartOrdersService#needValidateNum(java.util.List)
	 */
	@Override
	public boolean needValidateNum(String cartId) throws CoreException {
		StringBuffer sb = new StringBuffer();
		List<String> attrs = new ArrayList<String>();
		sb.append("select count(*) from ec_view_shelf where product_id in ( ");
		sb.append("select prod_id from ec_cart_order_product where prod_tp != 2 and cart_id= ? ");
		sb.append(") and is_validate_num = 'Y' ");
		attrs.add(cartId);
		List list = getDao().getSQLQueryByList(sb.toString(), attrs, 0, -1);
		if (Integer.parseInt(list.get(0).toString()) > 0) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public void checkCode(String imageId, String inputCode) throws CoreException {
		if (null == imageId || StringUtils.isBlank(imageId)) {
			throw new CoreException("验证码不可为空");
		}
		if (null == inputCode || StringUtils.isBlank(inputCode)) {
			throw new CoreException("验证码不可为空");
		}
		try {
			ImageValid imageValid = new ImageValid();
			imageValid.setId(imageId);
			imageValid.setValidData(inputCode);
			memberService.isImageValid(imageValid);
		} catch (Exception e) {
			throw new CoreException("验证码不符");
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.ec.shopping.service.CartOrdersService#chkVolumeOfCartOrderDetail(java.lang.String)
	 */
	@Override
	public Map<String, String> chkVolumeOfCartOrderDetail(String cartId) throws CoreException {
		StringBuffer sb = new StringBuffer();
		List<String> attrs = new ArrayList<String>();
		sb.append("select p.product_id,p.product_name,p.product_weight,p.product_volume ");
		sb.append("from ec_product_main p,ec_cart_order_detail d ");
		sb.append("where ");
		sb.append("((p.product_weight / 1000 ) > ? or (p.product_volume / ? ) > ? ) and ");
		// sb.append("(p.product_weight / 1000 ) > ? and ");
		sb.append("p.is_scm <> 'Y' and p.product_id = d.prod_id and d.cart_id= ? ");
		attrs.add(ServerValue.getProdWeight());
		attrs.add(ServerValue.getProdVolumeWeight());
		attrs.add(ServerValue.getProdWeight());
		attrs.add(cartId);
		List list = getDao().getSQLQueryByList(sb.toString(), attrs, 0, -1);
		Map<String, String> prodVolumeMap = new HashMap<String, String>();
		if (null != list && list.size() > 0) {
			Object[] obj = null;
			for (int i = 0; i < list.size(); i++) {
				obj = (Object[]) list.get(i);
				prodVolumeMap.put(obj[0].toString(), obj[1].toString());
			}
		}
		return prodVolumeMap;
	}

	@Transactional(readOnly = false, timeout = 5)
	public CartOrders addProductForTuangou(String memberId, CartOrders cartEntity, String productId, Long specId,
			int qty, String categoryPath) throws CoreException {
		return addProductBaseForTuangou(memberId, cartEntity, productId, specId, qty, categoryPath, true);
	}

	private CartOrders addProductBaseForTuangou(String memberId, CartOrders entity, String productId, Long specId,
			int qty, String categoryPath, boolean skipZeroPresent) throws CoreException {
		if (entity == null) {
			throw new CoreException("errors.cart.null", memberId);
		}

		Product product = productService.get(productId);
		Shelf shelf = null;
		Specification spec = null;
		SpecificationInventory specInv = null;
		// 检核商品主档是否存在
		if (product == null) {
			throw new CoreException("errors.product.null", productId);
		} else {
			// 若 categoryPath 未传入, 预设为 product.mainCategory.categoryPath
			if (StringUtils.isBlank(categoryPath)) {
				Category c = categoryService.get(Long.valueOf(product.getMainCategoryID()));
				categoryPath = c.getCategoryPath();
			} else {
				// 有傳入 categoryPath
				Map<String, ProductCategory> m = productService.getProductCategoryByProduct(productId);
				if (NumberUtils.isNumber(categoryPath)) {
					// 修正 categoryPath 傳入 categoryId, 並驗證是有正確上架目錄
					if (m.get(categoryPath) != null) {
						categoryPath = m.get(categoryPath).getCategoryPath();
					} else {
						// 找不到 categoryPath
						Category c = categoryService.get(Long.valueOf(product.getMainCategoryID()));
						categoryPath = c.getCategoryPath();
					}
				} else {
					boolean hasPC = false;
					for (ProductCategory pc : m.values()) {
						if (pc.getCategoryPath().equals(categoryPath)) {
							hasPC = true;
						}
					}
					if (!hasPC) {
						logger.error("上架目錄檔不正確, cartId:{}, productId:{}, categoryPath:{}", new Object[] { entity.getCartId(),
								productId, categoryPath });
						// 上架目錄檔不正確, 重新複寫為 product.mainCategory.categpryPath
						Category c = categoryService.get(Long.valueOf(product.getMainCategoryID()));
						categoryPath = c.getCategoryPath();
					}
				}
			}

			Map<String, Specification> specMap = productService.getSpecifications(productId);
			// 未给予 spec
			if (specId == null || specId.intValue() == 0) {
				// 找寻第一个 spec 作为 default spec
				if (specMap != null && !specMap.isEmpty()) {
					spec = specMap.values().iterator().next();
				}
			} else {
				if (specMap != null && !specMap.isEmpty()) {
					spec = specMap.get(specId.toString());
				}
			}
			if (spec == null) {
				throw new CoreException("errors.specification.null", productId);
			}

			// 确认库存
			// try {
			// if (product.getProductType() != 6) {
			// logger.info("product.getProductType() != 6:{}");
			// specInv = productService.getSpecificationInventory(productId, spec.getSpecificationId());
			// }
			// qty = checkSpecInvReturnQty(product, spec, specInv, qty);
			// } catch (Exception e) {
			// e.printStackTrace();
			// }

			// 判斷是否為上架档,否則new Shelf
			shelf = shelfService.getActiveShelfByProductId(productId);
			if (shelf == null) {
				shelf = new Shelf();
				shelf.setShelfPrice(product.getListPrice());
			}
		}
		CartOrderProduct cop = null;
		CartOrderProductDetail copd = null;
		cop = new CartOrderProduct(product, spec, shelf, categoryPath, qty, null);
		entity.addCartOrderProduct(cop);
		// logger.debug("op seq:{}", cop.getProdSeq());
		copd = new CartOrderProductDetail(product, spec, shelf, qty, null);
		cop.addDetail(copd);
		// logger.debug("opd seq:{}/{}", copd.getProdSeq(), copd.getDetailSeq());

		// for (CartOrderProduct cop_ : entity.getCartOrderProducts()) {
		// System.out.println(cop_.getProdSpecName());
		// }
		return save(entity);
	}

	@Transactional(readOnly = false)
	public CartOrders createCartForTuangou(String memberId, String productId, List<String> productOption, Long specId,
			int qty, String categoryPath, List<String> addOnProductId) throws CoreException {
		CartOrders cart = createCartBase(memberId, productId, productOption, specId, qty, categoryPath, addOnProductId);
		if (StringUtils.isNotBlank(productId)) {
			cart = addProductForTuangou(memberId, cart, productId, specId, qty, categoryPath);
		}
		return cart;
	}

}
